﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОписаниеПеременных

&НаКлиенте
Перем ПростойЗаголовокПроцедурыОписания;
&НаКлиенте
Перем ПараметрыПодключаемогоОбработчика;

#КонецОбласти

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	ЗапускИзКонфигурации = ТипЗнч(ОбъектОбработки()) = Тип("ОбработкаОбъект.ОписаниеОбработчиковОбновления");
	ИнициализироватьКонстантыОбработки();
	Элементы.КаталогФайловОшибок.Видимость = Элементы.ВыполнитьТестПостроенияОчереди.Видимость;
	
	УстановитьУсловноеОформление();
	
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
#Если ВебКлиент Тогда
	ВызватьИсключение НСтр("ru = 'Работа в web-клиенте не поддерживается.'");
#КонецЕсли
	
	Если СтрНайти(ПараметрЗапуска,"=") > 0 Тогда
		
		СтруктураПараметров = ПолучитьПараметрыИзСтроки(ПараметрЗапуска);
		
		Если Не ЗначениеЗаполнено(КаталогФайловОшибок) Тогда
			КаталогФайловОшибок = ВременныйКаталог();
		КонецЕсли; 
		
		Если СтруктураПараметров.Свойство("ErrorLogFolder") Тогда
			КаталогФайловОшибок = СтруктураПараметров.ErrorLogFolder;
		КонецЕсли;
		
		Если СтруктураПараметров.Свойство("ErrorAddInfo") Тогда
			ДополнениеТекстаОшибки = СтруктураПараметров.ErrorAddInfo;
		КонецЕсли;
		
		Если СтруктураПараметров.Свойство("ResultFile") Тогда
			ФайлРезультата = СтруктураПараметров.ResultFile;
		КонецЕсли;
		
#Если НЕ ВебКлиент Тогда
		Если СтруктураПараметров.Свойство("DetectionTime") И ЗначениеЗаполнено(СтруктураПараметров.DetectionTime) Тогда
			ДатаОбнаруженияОшибки = XMLЗначение(Тип("Дата"), СтруктураПараметров.DetectionTime);
		КонецЕсли;
#КонецЕсли
		
		Если СтруктураПараметров.Свойство("RepoPath") Тогда
			АдресРепозитория = СтруктураПараметров.RepoPath;
		КонецЕсли;
		
		ЗапуститьПроверку = СтрНайти(ПараметрЗапуска,"Выполнить") <> 0;
		ЗавершатьРаботу   = ЗапуститьПроверку;
		
		Попытка
			
			Если ЗапуститьПроверку Тогда
				ВыполнитьТестПостроенияОчереди(Неопределено);
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибке(ФайлРезультата);
			
		КонецПопытки; 
		
		Попытка
			
			Если ЗапуститьПроверку И ЗначениеЗаполнено(ФайлРезультата) Тогда
				Результат = Новый ТекстовыйДокумент;
				Результат.УстановитьТекст(Объект.Ошибки.Количество());
				Результат.Записать(ФайлРезультата);
			КонецЕсли;
			
		Исключение
			
			ЗаписатьИнформациюОбОшибке(ФайлРезультата);
			
		КонецПопытки;
		
		Если ЗавершатьРаботу Тогда
			ПрекратитьРаботуСистемы();
		КонецЕсли;
		
	КонецЕсли;
	
	ПодключитьОбработчикОжидания("ВыполнитьЗагрузкуОбработчиков", 0.1, Истина);
	
	ОформитьГруппуНастроек();
	Если РасширенныйРежимФормы Тогда
		УстановитьРасширенныйРежим();
	Иначе
		УстановитьУпрощенныйРежим();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	
	Если Модифицированность И НЕ ЗавершениеРаботы Тогда
		Отказ = Истина;
		ОбработчикОтвета = Новый ОписаниеОповещения("ЗавершениеЗакрытияФормы", ЭтотОбъект);
		ПоказатьВопрос(ОбработчикОтвета, НСтр("ru = 'Данные были изменены. Сохранить изменения в репозиторий?'"), РежимДиалогаВопрос.ДаНетОтмена);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ЗавершениеЗакрытияФормы(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = КодВозвратаДиалога.Да Тогда
		Модифицированность = Ложь;
		ЗаписатьДанныеНаДиск();
		Закрыть();
	ИначеЕсли Результат = КодВозвратаДиалога.Отмена Тогда
		// ничего не делаем
	Иначе
		Модифицированность = Ложь;
		Закрыть();
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ПередЗагрузкойДанныхИзНастроекНаСервере(Настройки)
	
	Объект.КаталогSRC = Настройки["Объект.КаталогSRC"];
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	
	Если ИмяСобытия = "ИзменилосьОписаниеОбработчикаОбновления" Тогда
		ОбновитьДанныеОКонфликтахОбработчика(Параметр);
		Оповестить("ОбновленыДанныеОКонфликтахОбработчикаОбновления", Параметр);
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура КаталогSRCНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	#Если НЕ ВебКлиент Тогда
		СтандартнаяОбработка = Ложь;
		
		ОбработчикВыбораФайла = Новый ОписаниеОповещения("ДиалогВыбораКаталогаЗавершение", ЭтотОбъект, "КаталогSRC");
		ФайловаяСистемаКлиент.ВыбратьКаталог(ОбработчикВыбораФайла, НСтр("ru = 'Укажите каталог SRC'"), Объект.КаталогSRC);
		
	#КонецЕсли
КонецПроцедуры

&НаКлиенте
Процедура КаталогSRCОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	Объект.КаталогSRC = ДобавитьРазделительПутиВКонец(Текст);
	
КонецПроцедуры

&НаКлиенте
Процедура КаталогФайловОшибокНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	#Если НЕ ВебКлиент Тогда
		СтандартнаяОбработка = Ложь;
		
		ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.ВыборКаталога);
		ДиалогВыбораФайла.ПолноеИмяФайла = КаталогФайловОшибок;
		ОбработчикВыбораФайла = Новый ОписаниеОповещения("ДиалогВыбораКаталогаЗавершение", ЭтотОбъект, "КаталогФайловОшибок");
		ФайловаяСистемаКлиент.ВыбратьКаталог(ОбработчикВыбораФайла, НСтр("ru = 'Укажите каталог файлов ошибок'"), КаталогФайловОшибок);
	#КонецЕсли
КонецПроцедуры

&НаКлиенте
Процедура КаталогФайловОшибокОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	КаталогФайловОшибок = ДобавитьРазделительПутиВКонец(Текст);
	ОформитьГруппуНастроек();
	
КонецПроцедуры

&НаКлиенте
Процедура ПодсистемаОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	ПодключитьОбработчикОжидания("Подключаемый_ОбработкаВыбораПодсистемы", 0.1, Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ОбработкаВыбораПодсистемы()
	
	Если ЗначениеЗаполнено(ТекущаяБиблиотека) Тогда
		Отбор = Новый Структура("Подсистема", ТекущаяБиблиотека);
		УстановитьОтборОбработчиков(Отбор);
	Иначе
		ОтключитьОтборОбработчиков("Подсистема");
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ИзменяемыйОбъектПриИзменении(Элемент)
	
	ПриИзмененииОбъектаПоискаНаСервере("ИзменяемыеОбъекты", ИзменяемыйОбъект);
	
КонецПроцедуры

&НаКлиенте
Процедура ИзменяемыйОбъектОчистка(Элемент, СтандартнаяОбработка)
	
	ПриИзмененииОбъектаПоискаНаСервере("ИзменяемыеОбъекты", ИзменяемыйОбъект);
	
КонецПроцедуры

&НаКлиенте
Процедура ЧитаемыйОбъектПриИзменении(Элемент)
	
	ПриИзмененииОбъектаПоискаНаСервере("ЧитаемыеОбъекты", ЧитаемыйОбъект);
	
КонецПроцедуры

&НаКлиенте
Процедура ЧитаемыйОбъектОчистка(Элемент, СтандартнаяОбработка)
	
	ПриИзмененииОбъектаПоискаНаСервере("ЧитаемыеОбъекты", ЧитаемыйОбъект);
	
КонецПроцедуры

&НаКлиенте
Процедура БыстрыеОтборыОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	Если НавигационнаяСсылкаФорматированнойСтроки = "Прочие" Тогда
		ВыборБыстрогоОтбора = Новый ОписаниеОповещения("ОбработкаВыбораБыстрогоОтбора", ЭтотОбъект);
		ПрочиеБыстрыеОтборы.ПоказатьВыборЭлемента(ВыборБыстрогоОтбора);
		Возврат;
	Иначе
		УстановитьБыстрыйОтбор(НавигационнаяСсылкаФорматированнойСтроки);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаВыбораБыстрогоОтбора(Результат, ДополнительныйПараметры) Экспорт
	
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	УстановитьБыстрыйОтбор(Результат);
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормы

&НаКлиенте
Процедура ОбработчикиОбновленияВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
	
	ОткрытьРедакторОписанияОбработчика(Элемент.ТекущиеДанные.Ссылка);
	
КонецПроцедуры

&НаКлиенте
Процедура ЗавершениеРедактированияОбработчика(Результат, ДополнительныеПараметры) Экспорт
	
	Если ТекущийЭлемент <> Неопределено И ТекущийЭлемент.Имя <> "ОбработчикиОбновления" Тогда
		ТекущийЭлемент = Элементы.ОбработчикиОбновления;
		Если ТекущийЭлемент.ТекущийЭлемент  <> Неопределено И ТекущийЭлемент.ТекущийЭлемент.Имя <> "ОбработчикиОбновленияПроцедура" Тогда
			ТекущийЭлемент.ТекущийЭлемент = Элементы.ОбработчикиОбновленияПроцедура;
		КонецЕсли;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Результат) Тогда
		ОбновитьДанныеОбработчика(Результат);
	ИначеЕсли Элементы.ОбработчикиОбновления.ТекущиеДанные <> Неопределено 
			И Элементы.ОбработчикиОбновления.ТекущиеДанные.НоваяСтрока Тогда
		ТекущаяСтрока = Объект.ОбработчикиОбновления.НайтиПоИдентификатору(Элементы.ОбработчикиОбновления.ТекущаяСтрока);
		Объект.ОбработчикиОбновления.Удалить(ТекущаяСтрока);
		Элементы.ОбработчикиОбновления.ТекущаяСтрока = ИсходнаяТекущаяСтрока;
	КонецЕсли;
	ИсходнаяТекущаяСтрока = 0;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработчикиОбновленияПередУдалением(Элемент, Отказ)
	
	Отказ = Истина;
	ОбработчикОтвета = Новый ОписаниеОповещения("ЗавершениеУдаленияОписанияОбработчика", ЭтотОбъект);
	ТекстВопроса = НСтр("ru = 'Удалить описание обработчика?'");
	ПоказатьВопрос(ОбработчикОтвета, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
	
КонецПроцедуры

&НаКлиенте
Процедура ЗавершениеУдаленияОписанияОбработчика(Результат, ДополнительныеСвойства) Экспорт
	
	Элемент = Элементы.ОбработчикиОбновления;
	Если Результат = КодВозвратаДиалога.Да Тогда
		Модифицированность = Истина;
		ИсходнаяТекущаяСтрока = Элемент.ТекущаяСтрока;
		Если Элемент.ВыделенныеСтроки.Количество() > 0 Тогда
			УдаляемыеСтроки = Новый Массив;
			Для Каждого ИдентификаторСтроки Из Элемент.ВыделенныеСтроки Цикл
				УдаляемыеСтроки.Добавить(ИдентификаторСтроки);
			КонецЦикла;
			УдалитьОписаниеОбработчиков(УдаляемыеСтроки);
		Иначе
			УдалитьОписаниеОбработчиков(Элемент.ТекущиеДанные.Ссылка);
		КонецЕсли;
		Элемент.ТекущаяСтрока = ИсходнаяТекущаяСтрока+1;
		ИсходнаяТекущаяСтрока = 0;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработчикиОбновленияПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
	
	ИсходнаяТекущаяСтрока = Элемент.ТекущаяСтрока;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработчикиОбновленияПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
	
	Если НоваяСтрока Тогда
		ИсходнаяСсылка = Элемент.ТекущиеДанные.Ссылка;
		Элемент.ТекущиеДанные.НоваяСтрока = Истина;
		Элемент.ТекущиеДанные.Изменен = Истина;
		Элемент.ТекущиеДанные.Ссылка = Новый УникальныйИдентификатор;
		Если Копирование Тогда
			Элемент.ТекущиеДанные.Идентификатор = "";
		Иначе
			Элемент.ТекущиеДанные.РежимВыполнения = "Отложенно";
			Элемент.ТекущиеДанные.РежимВыполненияОтложенныхОбработчиков = "Параллельно";
			Если ЗначениеЗаполнено(Элемент.ОтборСтрок) И Элемент.ОтборСтрок.Свойство("Подсистема") Тогда
				Элемент.ТекущиеДанные.Подсистема = Элемент.ОтборСтрок.Подсистема;
			КонецЕсли;
		КонецЕсли;
		ОткрытьРедакторОписанияОбработчика(Элемент.ТекущиеДанные.Ссылка, НоваяСтрока, ИсходнаяСсылка);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработчикиОбновленияТехПроектПриИзменении(Элемент)
	
	ЗаполнитьБыстрыеОтборы();
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ЗагрузитьОбработчики(Команда)
	
	ОбработчикиТехПроекта = ЗагрузитьСписокОбработчиковТехПроекта();
	ЗагрузитьИзТекущейКонфигурацииНаСервере(ОбработчикиТехПроекта);
	Элементы.ГруппаНастройкиЗагрузкиВыгрузки.Скрыть();
	
КонецПроцедуры

&НаКлиенте
Процедура ПостроитьОчередь(Команда)
	
	ПостроитьОчередьНаСервере();
	Элементы.ГруппаНастройкиЗагрузкиВыгрузки.Скрыть();
	
КонецПроцедуры

&НаКлиенте
Процедура СохранитьВРепозиторий(Команда)
	
	Если НЕ ПравильноУказанКаталогSRC() Тогда
		Возврат;
	КонецЕсли;
	
	ЗаписатьДанныеНаДиск();
	Элементы.ГруппаНастройкиЗагрузкиВыгрузки.Скрыть();
	Модифицированность = Ложь;
	
КонецПроцедуры

&НаКлиенте
Процедура СохранитьВРепозиторийВсеОбработчики(Команда)
	
	Если НЕ ПравильноУказанКаталогSRC() Тогда
		Возврат;
	КонецЕсли;
	
	ПараметрыСохранения = Новый Структура("ВсеОбработчики", Истина);
	ОбработчикОтвета = Новый ОписаниеОповещения("ЗавершениеСохраненияВРепозиторий", ЭтотОбъект, ПараметрыСохранения);
	ТекстВопроса = НСтр("ru = 'Внимание! Будут перезаписаны все процедуры описания обработчиков обновления.
						|Продолжить?'");
	ПоказатьВопрос(ОбработчикОтвета, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
	Элементы.ГруппаНастройкиЗагрузкиВыгрузки.Скрыть();
	Модифицированность = Ложь;
	
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьКодОписанияОбработчиковОбновления(Команда)
	
	ПараметрыГенерацииКода = НовыеПараметрыГенерацииКода();
	Если РасширенныйРежимФормы Тогда
		ПараметрыГенерацииКода.ОбновитьОчередь = Ложь;
	Иначе
		ПараметрыГенерацииКода.ОписаниеВОбщемМодуле = Истина;
		ПараметрыГенерацииКода.ОбновитьСписокВызовов = Ложь;
	КонецЕсли;
	ПоказатьТекстыОписанияОбработчиковОбновления(ПараметрыГенерацииКода);
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьНомерСборкиОбработчикам(Команда)
	
	ДополнительныеПараметры = Новый Структура("НомерСборкиДляОбработчиков", Истина);
	ОбработчикОтвета = Новый ОписаниеОповещения("ЗавершениеВводаНомераСборки", ЭтотОбъект, ДополнительныеПараметры);
	НомераВерсии = СтрРазделить(ВерсияКонфигурации,".");
	ПоказатьВводЧисла(ОбработчикОтвета, Число(НомераВерсии[3])+1, НСтр("ru = 'Новый номер сборки'"));
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаписатьСписокОбработчиковТехПроекта(Команда)
	
	СохранитьСписокОбработчиковТехПроекта();
	
КонецПроцедуры

&НаКлиенте
Процедура ПереключитьРежимФормы(Команда)
	
	Если РасширенныйРежимФормы Тогда
		УстановитьУпрощенныйРежим();
	Иначе
		УстановитьРасширенныйРежим();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура СохранитьВФайл(Команда)
	
    #Если НЕ ВебКлиент Тогда
		
		ОбработчикВыбораФайла = Новый ОписаниеОповещения("ДиалогВыбораФайлаЗавершение", ЭтотОбъект, "");
		ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
		ДиалогВыбораФайла.Заголовок = НСтр("ru = 'Укажите имя файла'");
		ДиалогВыбораФайла.Фильтр = ФильтрФайловРезервнойКопии();
		ДиалогВыбораФайла.МножественныйВыбор = Ложь;
		ФайловаяСистемаКлиент.ПоказатьДиалогВыбора(ОбработчикВыбораФайла, ДиалогВыбораФайла);
		
	#КонецЕсли
	
КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьИзФайла(Команда)
	
	#Если НЕ ВебКлиент Тогда
		
		Оповещение = Новый ОписаниеОповещения("ВыбратьФайлПослеПомещенияФайла", ЭтотОбъект);
		ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла();
		ПараметрыЗагрузки.Диалог.Заголовок = НСтр("ru = 'Укажите файл'");
		ПараметрыЗагрузки.Диалог.Фильтр = ФильтрФайловРезервнойКопии();
		ПараметрыЗагрузки.ИдентификаторФормы = УникальныйИдентификатор;
		ФайловаяСистемаКлиент.ЗагрузитьФайл(Оповещение, ПараметрыЗагрузки);
		
	#КонецЕсли
	
КонецПроцедуры

#Область ПодменюОтладки

&НаКлиенте
Процедура ПроверитьКонфликты(Команда)
	
	ПроверитьКонфликтыНаСервере();
	
КонецПроцедуры

&НаКлиенте
Процедура ПриДобавленииОбработчиковОбновления_Вызовы(Команда)
	
	ПараметрыГенерацииКода = НовыеПараметрыГенерацииКода();
	ПараметрыГенерацииКода.ОбновитьОчередь = Ложь;
	ПоказатьТекстыОписанияОбработчиковОбновления(ПараметрыГенерацииКода);
	
КонецПроцедуры

&НаКлиенте
Процедура ПриДобавленииОбработчиковОбновления_Описания(Команда)
	
	ПараметрыГенерацииКода = НовыеПараметрыГенерацииКода();
	ПараметрыГенерацииКода.ОписаниеВОбщемМодуле = Истина;
	ПоказатьТекстыОписанияОбработчиковОбновления(ПараметрыГенерацииКода);
	
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьНастройки(Команда)
	
	ТекстыНастроек = ПолучитьТекстыНастроек();
	Для Каждого ТекстФайла Из ТекстыНастроек Цикл
		ТекстовыйДокумент = Новый ТекстовыйДокумент;
		ТекстовыйДокумент.УстановитьТекст(ТекстФайла.Значение);
		ТекстовыйДокумент.Показать(ТекстФайла.Представление);
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьТабличныеЧасти(Команда)
	
	ДанныеТаблиц = ВыгрузитьТаблицыВMXL();
	Для Каждого Таблица Из ДанныеТаблиц Цикл
		Таблица.Значение.Показать(Таблица.Ключ);
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьПриоритетыКонфликтыОбработчика(Команда)
	
	Если Элементы.ОбработчикиОбновления.ТекущиеДанные = Неопределено Тогда
		ПоказатьПредупреждение(,НСтр("ru = 'Не выбран обработчики обновления'"));
		Возврат;
	КонецЕсли;
	
	ДанныеТаблиц = ВыгрузитьТаблицыВMXL(
		Элементы.ОбработчикиОбновления.ТекущиеДанные.Ссылка, "ПриоритетыВыполнения,КонфликтыОбработчиков");
	Для Каждого Таблица Из ДанныеТаблиц Цикл
		Таблица.Значение.Показать(Таблица.Ключ);
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьОбъектыОбработчика(Команда)
	
	Если Элементы.ОбработчикиОбновления.ТекущиеДанные = Неопределено Тогда
		ПоказатьПредупреждение(,НСтр("ru = 'Не выбран обработчики обновления'"));
		Возврат;
	КонецЕсли;
	
	ДанныеТаблиц = ВыгрузитьТаблицыВMXL(
		Элементы.ОбработчикиОбновления.ТекущиеДанные.Ссылка, "ЧитаемыеОбъекты,ИзменяемыеОбъекты,БлокируемыеОбъекты");
	Для Каждого Таблица Из ДанныеТаблиц Цикл
		Таблица.Значение.Показать(Таблица.Ключ);
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьТестПостроенияОчереди(Команда)
	
	#Область ПроверкаКаталогаФайловОшибок
	Если Команда <> Неопределено Тогда
		Элементы.КаталогФайловОшибок.Видимость = Истина;
		ОформитьГруппуНастроек();
		Если НЕ ЗначениеЗаполнено(КаталогФайловОшибок) Тогда
			ОбщегоНазначенияКлиент.СообщитьПользователю(
				НСтр("ru = 'Не указан каталог файлов ошибок.'"),
				,
				,
				"КаталогФайловОшибок");
				Возврат;
		КонецЕсли;
	КонецЕсли;
	#КонецОбласти
	
	Объект.Ошибки.Очистить();
	ПостроитьОчередьНаСервере();
	Для Каждого Ошибка Из Объект.Ошибки Цикл
		ЗаписатьОшибку(Ошибка.ОбъектМетаданных, Ошибка.Сообщение);
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура РассчитатьОчередь(Команда)
	РассчитатьОчередьНаСервере();
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьТекстыВсехМодулей(Команда)
	
	ПараметрыГенерацииКода = НовыеПараметрыГенерацииКода();
	ПараметрыГенерацииКода.ОбновитьОчередь = Ложь;
	ПараметрыГенерацииКода.ТолькоИзмененные = Ложь; 
	ТекстыМодулей = ПолучитьТекстыМодулей(ПараметрыГенерацииКода);
	Для Каждого КодМодуля Из ТекстыМодулей Цикл
		ТекстовыйДокумент = Новый ТекстовыйДокумент;
		ТекстовыйДокумент.УстановитьТекст(КодМодуля.ТекстПроцедуры);
		ТекстовыйДокумент.Показать(КодМодуля.ИмяМодуля);
	КонецЦикла;
	Элементы.ГруппаНастройкиЗагрузкиВыгрузки.Скрыть();
	Модифицированность = Ложь;
	
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьТекстМодулей(Команда)
	
	ПараметрыГенерацииКода = НовыеПараметрыГенерацииКода();
	ПараметрыГенерацииКода.ТолькоИзмененные = Ложь;
	ПараметрыГенерацииКода.ТолькоВыделенные = Истина; 
	ТекстыМодулей = ПолучитьТекстыМодулей(ПараметрыГенерацииКода);
	Для Каждого КодМодуля Из ТекстыМодулей Цикл
		ТекстовыйДокумент = Новый ТекстовыйДокумент;
		ТекстовыйДокумент.УстановитьТекст(КодМодуля.ТекстПроцедуры);
		ТекстовыйДокумент.Показать(КодМодуля.ИмяМодуля);
	КонецЦикла;
	Элементы.ГруппаНастройкиЗагрузкиВыгрузки.Скрыть();
	Модифицированность = Ложь;
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьАвтоПорядок(Команда)
	
	Для Каждого Приоритет Из Объект.ПриоритетыВыполнения Цикл
		Приоритет.Порядок = Приоритет.ПорядокАвто;
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаСервере
Процедура УстановитьУсловноеОформление()
	
	УсловноеОформление.Элементы.Очистить();
	
	#Область СтатусИзмененаПроцедураПроверки
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ОбработчикиОбновленияСтатусПроблемы.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(Элементы.ОбработчикиОбновленияИзмененаПроцедураПроверки.ПутьКДанным);
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", СтатусИзмененаПроцедураПроверки);
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", WebЦвета.Золотистый);
	#КонецОбласти
	
	#Область СтатусЧтениеНизкогоПорядка
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ОбработчикиОбновленияСтатусПроблемы.Имя);
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(Элементы.ОбработчикиОбновленияЧтениеНизкогоПорядка.ПутьКДанным);
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("Текст", СтатусЧтениеНизкогоПорядка);
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветОсобогоТекста);
	#КонецОбласти
	
	#Область СтатусНеобходимАнализ
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
	ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.ОбработчикиОбновленияСтатусПроблемы.Имя);
	
	ГруппаИ = Элемент.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
	
		ОтборЭлемента = ГруппаИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
		ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(Элементы.ОбработчикиОбновленияЗаданПорядокВыполнения.ПутьКДанным);
		ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
		ОтборЭлемента.ПравоеЗначение = Ложь;
		
		ГруппаИЛИ = ГруппаИ.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
		
			ОтборЭлемента = ГруппаИЛИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
			ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(Элементы.ОбработчикиОбновленияЗаписьЧитаемых.ПутьКДанным);
			ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
			ОтборЭлемента.ПравоеЗначение = Истина;
			
			ОтборЭлемента = ГруппаИЛИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
			ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(Элементы.ОбработчикиОбновленияПовторнаяЗапись.ПутьКДанным);
			ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
			ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветТекста", ЦветаСтиля.ЦветОсобогоТекста);
	#КонецОбласти
	
	#Область ТехническийПроект
	Элемент = УсловноеОформление.Элементы.Добавить();
	
	Для Каждого ЭлементФормы Из Элементы.ОбработчикиОбновления.ПодчиненныеЭлементы Цикл
		ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
		ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(ЭлементФормы.Имя);
	КонецЦикла;
	
	ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(Элементы.ОбработчикиОбновленияТехПроект.ПутьКДанным);
	ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
	ОтборЭлемента.ПравоеЗначение = Истина;
	
	Элемент.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СеребристоСерый);
	#КонецОбласти
	
КонецПроцедуры

#Область ЗагрузкаОбработчиков

&НаКлиенте
Процедура ВыполнитьЗагрузкуОбработчиков()
	
	ПараметрыФормы = Новый Структура("ТекстСообщения", НСтр("ru = 'Выполняется загрузка обработчиков'"));
	ФормаДлительнойОперации = ОткрытьФорму("ОбщаяФорма.ДлительнаяОперация", ПараметрыФормы);
	ЗагрузитьОбработчики(Неопределено);
	ФормаДлительнойОперации.Закрыть();
	
КонецПроцедуры

&НаСервере
Процедура ЗагрузитьИзТекущейКонфигурацииНаСервере(ОбработчикиТехПроекта = Неопределено)
	
	Обработка = ОбъектОбработки();
	Обработка.ЗагрузитьОбработчики();
	ЗначениеВРеквизитФормы(Обработка, "Объект");
	
	Если ОбработчикиТехПроекта <> Неопределено Тогда
		Для Каждого Обработчик Из ОбработчикиТехПроекта Цикл
			Если СтрНайти(Обработчик,":") = 0 Тогда
				Продолжить;
			КонецЕсли;
			Данные = СтрРазделить(Обработчик, ":");
			Отбор = Новый Структура;
			Если ЗначениеЗаполнено(Данные[0]) Тогда
				Отбор.Вставить("Идентификатор", Данные[0]);
			КонецЕсли;
			Если ЗначениеЗаполнено(Данные[1]) Тогда
				Отбор.Вставить("Процедура", Данные[1]);
			КонецЕсли;
			НайденныеОбработчики = Объект.ОбработчикиОбновления.НайтиСтроки(Отбор);
			Для Каждого Найденный Из НайденныеОбработчики Цикл
				Найденный.ТехническийПроект = Истина;
			КонецЦикла;
		КонецЦикла;
	КонецЕсли;
	
	ОбновитьДанныеФормы(Обработка);
	
	ТекущаяБиблиотека = "";
	Модифицированность = Ложь;
	
КонецПроцедуры

&НаКлиенте
Функция ЗагрузитьСписокОбработчиковТехПроекта()
	
	ИмяФайла = КаталогНастроек() + "tech-project.updaters";
	
	Файл = Новый Файл(ИмяФайла);
	Если НЕ Файл.Существует() Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ФайлНастроек = Новый ТекстовыйДокумент;
	#Если НЕ ВебКлиент Тогда
	ФайлНастроек.Прочитать(ИмяФайла, КодировкаТекста.UTF8);
	#КонецЕсли
	ТекстФайла = ФайлНастроек.ПолучитьТекст();
	ОбработчикиТехПроекта = СтрРазделить(ТекстФайла, Символы.ПС);
	
	Возврат ОбработчикиТехПроекта;
	
КонецФункции

#КонецОбласти

#Область СохранениеВРепозиторий

&НаКлиенте
Функция ПравильноУказанКаталогSRC()
	
	Результат = Истина;
	Если НЕ ЗначениеЗаполнено(Объект.КаталогSRC) Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(
			НСтр("ru = 'Не указан путь к каталогу SRC'"),
			,
			,
			"Объект.КаталогSRC");
		Результат = Ложь;
	КонецЕсли;
	
	КаталогНаДиске = Новый Файл(Объект.КаталогSRC);
	Если НЕ КаталогНаДиске.Существует() Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(
			НСтр("ru = 'Не найден каталог SRC'"),
			,
			,
			"Объект.КаталогSRC");
		Результат = Ложь;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

&НаКлиенте
Процедура ЗавершениеСохраненияВРепозиторий(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = КодВозвратаДиалога.Да Тогда
		ЗаписатьДанныеНаДиск(ДополнительныеПараметры.ВсеОбработчики);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаписатьДанныеНаДиск(ВсеОбработчики = Ложь)
	
	ОчиститьСообщения();
	ПростойЗаголовокПроцедурыОписания = "Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт";
	ПараметрыГенерацииКода = НовыеПараметрыГенерацииКода();
	ПараметрыГенерацииКода.ТолькоИзмененные = НЕ ВсеОбработчики;
	ТекстыМодулей = ПолучитьТекстыМодулей(ПараметрыГенерацииКода);
	СохранитьВерсиюВКореньКонфигурации();
	Для Каждого ТекстМодуля Из ТекстыМодулей Цикл
		ЗаменитьПроцедуруМодуля(ТекстМодуля);
	КонецЦикла;
	СохранитьСписокОбработчиковТехПроекта();
	НовыйНомерСборкиКонфигурации = 0;
	
КонецПроцедуры

&НаКлиенте
Функция ДобавитьПроцедуруМодуля(Код)
	
	ДобавленаПроцедура = Ложь;
	ПолноеИмяФайла = Объект.КаталогSRC + Код.ПутьМодуля;
	СтрокиМодуля = ТекстФайлаВМассив(ПолноеИмяФайла);
	ЭтоМодульМенеджера = СтрНайти(Код.ИмяМодуля, ".") > 0;
	ИмяПроцедуры = ИмяПроцедуры(Код.ЗаголовокПроцедуры);
	
	КомментарийПроцедуры = 
	"// см. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления
	|%1";
	ТекстПроцедуры = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(КомментарийПроцедуры, Код.ТекстПроцедуры);
	
	// Если Модуль пустой заполнить по шаблону пустого модуля - только модули менеджера
	Если ЭтоМодульМенеджера И СтрокиМодуля.Количество() = 0 Тогда
		ПустойМодульМенеджера = 
		"#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
		|
		|#Область СлужебныеПроцедурыИФункции
		|
		|#Область ОбновлениеИнформационнойБазы
		|
		|%1
		|
		|#КонецОбласти
		|
		|#КонецОбласти
		|
		|#КонецЕсли";
		НовыйТекст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ПустойМодульМенеджера, ТекстПроцедуры);
		ЗаписатьТекстМодуля(НовыйТекст, ПолноеИмяФайла);
		
		Шаблон = НСтр("ru = 'В модуле ""%1"" добавлена процедура ""%2""'");
		ОбщегоНазначенияКлиент.СообщитьПользователю(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, Код.ИмяМодуля, ИмяПроцедуры));
		Возврат Истина;
	КонецЕсли;
	
	ЕстьПроцедураОписания = СтрокиМодуля.Найти(ПростойЗаголовокПроцедурыОписания) <> Неопределено
		ИЛИ СтрокиМодуля.Найти("Процедура ОписаниеОбработчиковОбновления(Обработчики) Экспорт") <> Неопределено;
	
	ЕстьБиблиотечнаяПроцедураОписания = Ложь;
	Если Код.ЭтоПроцедураОписания Тогда
		Для Каждого ИмяБиблиотеки Из Код.ИменаБиблиотек Цикл
			ШаблонЗаголовка = "Процедура ОписаниеОбработчиковОбновления%1(Обработчики) Экспорт";
			НайденныйЗаголовокПроцедуры = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонЗаголовка, ИмяБиблиотеки);
			Если СтрокиМодуля.Найти(НайденныйЗаголовокПроцедуры) <> Неопределено Тогда
				ЕстьБиблиотечнаяПроцедураОписания = Истина;
				Прервать;
			КонецЕсли;
			// "Процедура ПриДобавленииОбработчиковОбновления%1(Обработчики) Экспорт"
			ШаблонЗаголовка = СтрЗаменить(ПростойЗаголовокПроцедурыОписания, "(", "%1(");
			НайденныйЗаголовокПроцедуры = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонЗаголовка, ИмяБиблиотеки);
			Если СтрокиМодуля.Найти(НайденныйЗаголовокПроцедуры) <> Неопределено Тогда
				ЕстьБиблиотечнаяПроцедураОписания = Истина;
				Прервать;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	ЕстьПереданнаяПроцедура = СтрокиМодуля.Найти(Код.ЗаголовокПроцедуры) <> Неопределено;
	ПереданаПростаяПроцедура = Код.ЗаголовокПроцедуры = ПростойЗаголовокПроцедурыОписания;
	
	// Если процедура уже есть - уходим
	Если ЕстьПереданнаяПроцедура
		ИЛИ ЕстьПроцедураОписания
		ИЛИ ЕстьБиблиотечнаяПроцедураОписания И ПереданаПростаяПроцедура Тогда
		Возврат ДобавленаПроцедура;
	КонецЕсли;
	
	// Если есть #Область ОбновлениеНовыхВерсийИБ или #Область ОбновлениеИнформационнойБазы,
	// то вставить сразу после начала области
	Индекс = СтрокиМодуля.Найти("#Область ОбновлениеИнформационнойБазы");
	Если Индекс <> Неопределено Тогда
		Индекс = Индекс + 1;
		СтрокиМодуля.Вставить(Индекс, "");
		СтрокиПроцедуры = СтрРазделить(ТекстПроцедуры, Символы.ПС);
		Для Каждого НоваяСтрока Из СтрокиПроцедуры Цикл
			Индекс = Индекс + 1;
			СтрокиМодуля.Вставить(Индекс, НоваяСтрока);
		КонецЦикла;
		ДобавленаПроцедура = Истина;
	КонецЕсли;
	
	// Если есть процедура обработки, то вставить перед ней
	Если НЕ ДобавленаПроцедура И НЕ ПустаяСтрока(Код.ПроцедураОбработки) Тогда
		Имена = СтрРазделить(Код.ПроцедураОбработки, ".");
		ИмяПроцедурыОбновления = Имена[Имена.ВГраница()];
		ИндексВставки = СтрокиМодуля.Найти("Процедура "+ИмяПроцедурыОбновления+"(Параметры) Экспорт");
		Если ИндексВставки <> Неопределено Тогда
			СтрокиПроцедуры = СтрРазделить(ТекстПроцедуры, Символы.ПС);
			СтрокиМодуля.Вставить(ИндексВставки, "");
			Индекс = СтрокиПроцедуры.ВГраница();
			Для СдвигКНачалу = 0 По СтрокиПроцедуры.ВГраница() Цикл
				СтрокаПроцедуры = СтрокиПроцедуры[Индекс - СдвигКНачалу];
				СтрокиМодуля.Вставить(ИндексВставки, СтрокаПроцедуры);
			КонецЦикла;
			ДобавленаПроцедура = Истина;
		КонецЕсли;
	КонецЕсли;
	
	ТекстОбласти = 
	"#Область ОбновлениеИнформационнойБазы
	|
	|%1
	|
	|#КонецОбласти";
	
	// Если нет области обновления и процедуры обработки, то искать СлужебныеПроцедурыИФункции и вставить в нее первой областью
	Если НЕ ДобавленаПроцедура И НЕ ПустаяСтрока(Код.ПроцедураОбработки) Тогда
		Индекс = СтрокиМодуля.Найти("#Область СлужебныеПроцедурыИФункции");
		Если Индекс <> Неопределено Тогда
			ТекстОбласти = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОбласти, ТекстПроцедуры);
			Индекс = Индекс + 1;
			СтрокиМодуля.Вставить(Индекс, "");
			СтрокиОбласти = СтрРазделить(ТекстОбласти, Символы.ПС);
			Для Каждого НоваяСтрока Из СтрокиОбласти Цикл
				Индекс = Индекс + 1;
				СтрокиМодуля.Вставить(Индекс, НоваяСтрока);
			КонецЦикла;
			ДобавленаПроцедура = Истина;
		КонецЕсли;
	КонецЕсли;
	
	// Если нет области обновления, процедуры обработки и области СлужебныеПроцедурыИФункции, то добавляем в конец модуля
	Если НЕ ДобавленаПроцедура И НЕ ПустаяСтрока(Код.ПроцедураОбработки) Тогда
		
		ТекстОбласти = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОбласти, ТекстПроцедуры);
		
		ИндексВставки = СтрокиМодуля.ВГраница();
		ПоследняяСтрока = СокрЛП(СтрокиМодуля[ИндексВставки]);
		Пока ПустаяСтрока(ПоследняяСтрока) Цикл
			ИндексВставки = ИндексВставки - 1;
			ПоследняяСтрока = СокрЛП(СтрокиМодуля[ИндексВставки]);
		КонецЦикла;
		
		Если ПоследняяСтрока = "#КонецЕсли" Тогда
			ИндексВставки = ИндексВставки - 1;
			СтрокиМодуля.Вставить(ИндексВставки, "");
			СтрокиОбласти = СтрРазделить(ТекстОбласти, Символы.ПС);
			Индекс = СтрокиОбласти.ВГраница();
			Для СдвигКНачалу = 0 По СтрокиОбласти.ВГраница() Цикл
				СтрокаПроцедуры = СтрокиОбласти[Индекс - СдвигКНачалу];
				СтрокиМодуля.Вставить(ИндексВставки, СтрокаПроцедуры);
			КонецЦикла;
		Иначе
			СтрокиМодуля.Добавить("");
			СтрокиОбласти = СтрРазделить(ТекстОбласти, Символы.ПС);
			Для Каждого НоваяСтрока Из СтрокиОбласти Цикл
				СтрокиМодуля.Добавить(НоваяСтрока);
			КонецЦикла;
		КонецЕсли;
		ДобавленаПроцедура = Истина;
	КонецЕсли;
	
	Если ДобавленаПроцедура Тогда
		НовыйТекст = СтрСоединить(СтрокиМодуля, Символы.ПС);
		ЗаписатьТекстМодуля(НовыйТекст, ПолноеИмяФайла);
		
		Шаблон = НСтр("ru = 'В модуле ""%1"" добавлена процедура ""%2""'");
		ОбщегоНазначенияКлиент.СообщитьПользователю(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, Код.ИмяМодуля, ИмяПроцедуры));
	Иначе
		Шаблон = НСтр("ru = 'В модуле ""%1"" не удалось добавить процедуру ""%2""
		|Возможно в модуле не задана область ""%3"".
		|Добавьте процедуру или область вручную и повторите запись обработчиков.'");
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, Код.ИмяМодуля, ИмяПроцедуры, "ОбновлениеИнформационнойБазы");
		ВызватьИсключение ТекстСообщения;
	КонецЕсли;
	
	Возврат ДобавленаПроцедура;
	
КонецФункции

&НаКлиенте
Процедура ЗаменитьПроцедуруМодуля(Код)
	
	Если Код.ЭтоПроцедураОписания И ДобавитьПроцедуруМодуля(Код) Тогда
		Возврат;
	КонецЕсли;
	
	ПолноеИмяФайла = Объект.КаталогSRC + Код.ПутьМодуля;
	НовыйМодуль = Новый ТекстовыйДокумент;
	
	НовыйТекстПроцедуры = СтрРазделить(Код.ТекстПроцедуры, Символы.ПС);
	ОкончаниеПроцедуры = НовыйТекстПроцедуры[НовыйТекстПроцедуры.ВГраница()];
	
	УстановитьВерсию = ЗначениеЗаполнено(Код.Версия);
	
	ВыполненаЗамена = Ложь;
	УстановленаВерсия = Ложь;
	ЭтоМодульОбновления = СтрНачинаетсяС(Код.ИмяМодуля, "ОбновлениеИнформационнойБазы");
	#Если НЕ ВебКлиент Тогда
	Модуль = Новый ЧтениеТекста;
	Модуль.Открыть(ПолноеИмяФайла, "UTF-8");
	СтрокаМодуля = "";
	Пока СтрокаМодуля <> Неопределено Цикл

		СтрокаМодуля = Модуль.ПрочитатьСтроку();
		Если СтрокаМодуля = Неопределено Тогда
			Прервать;
		КонецЕсли;
	
		#Область ПриДобавленииПодсистемы
		Если УстановитьВерсию И СокрЛП(СтрокаМодуля) = Код.ПроцедураВерсии Тогда
			НовыйМодуль.ДобавитьСтроку(СтрокаМодуля);
			Пока СтрНайти(СтрокаМодуля, "Описание.Версия =") = 0 Цикл
				СтрокаМодуля = Модуль.ПрочитатьСтроку();
				Если СтрНайти(СтрокаМодуля, "Описание.Версия =") > 0 И СтрНайти(СтрокаМодуля, Код.Версия) = 0 Тогда
					УстановленаВерсия = Истина;
					СтрокаМодуля = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("	Описание.Версия = ""%1"";", Код.Версия);
				КонецЕсли;
				Если СтрНайти(СокрЛП(СтрокаМодуля), "Процедура") = 1 Тогда
					НовыйМодуль.ДобавитьСтроку(СтрокаМодуля);
					Прервать;
				КонецЕсли;
				НовыйМодуль.ДобавитьСтроку(СтрокаМодуля);
			КонецЦикла;
			Продолжить;
		КонецЕсли;
		#КонецОбласти
		
		#Область ЗаменитьКомментарий
		// АПК:1297-выкл комментарий в коде конфигурации
		Если Код.ЭтоПроцедураОписания 
			И СтрНайти(СтрокаМодуля, "--// Добавляет в список процедуры-обработчики обновления данных ИБ") > 0 Тогда
			СтрокаМодуля = ПропуститьСтрокиДо(Модуль, "Обработчики - см. ОбновлениеИнформационнойБазы.НоваяТаблицаОбработчиковОбновления");
			Если СтрНайти(СтрокаМодуля, "Процедура") = 0 Тогда
				СтрокаМодуля = Модуль.ПрочитатьСтроку();
				СтрокаМодуля = "// см. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления";
			КонецЕсли;
		КонецЕсли;
		// АПК:1297-вкл
		#КонецОбласти
		
		#Область ПриДобавленииОбработчиковОбновления
		ЭтоБиблиотечнаяПроцедураОписания = Ложь;
		БиблиотечныйЗаголовокПроцедуры = Код.ЗаголовокПроцедуры;
		Если НЕ ВыполненаЗамена 
			И Код.ЭтоПроцедураОписания
			И (СтрНайти(СтрокаМодуля, "Процедура ОписаниеОбработчиковОбновления") > 0
				ИЛИ СтрНайти(СтрокаМодуля, "Процедура ПриДобавленииОбработчиковОбновления") > 0)
			И СтрНайти(СтрокаМодуля, БиблиотечныйЗаголовокПроцедуры) = 0 Тогда
			Для Каждого ИмяБиблиотеки Из Код.ИменаБиблиотек Цикл
				БиблиотечныйЗаголовокПроцедуры = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("Процедура ОписаниеОбработчиковОбновления%1(Обработчики) Экспорт", ИмяБиблиотеки);
				Если СтрНайти(СтрокаМодуля, БиблиотечныйЗаголовокПроцедуры) > 0 Тогда
					ЭтоБиблиотечнаяПроцедураОписания = Истина;
					Прервать;
				КонецЕсли;
				БиблиотечныйЗаголовокПроцедуры = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("Процедура ПриДобавленииОбработчиковОбновления%1(Обработчики) Экспорт", ИмяБиблиотеки);
				Если СтрНайти(СтрокаМодуля, БиблиотечныйЗаголовокПроцедуры) > 0 Тогда
					ЭтоБиблиотечнаяПроцедураОписания = Истина;
					Прервать;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		
		Если СокрЛП(СтрокаМодуля) = Код.ЗаголовокПроцедуры 
			ИЛИ (НЕ ЭтоМодульОбновления
				И Код.ЭтоПроцедураОписания
				И (СокрЛП(СтрокаМодуля) = ПростойЗаголовокПроцедурыОписания
						ИЛИ СокрЛП(СтрокаМодуля) = "Процедура ОписаниеОбработчиковОбновления(Обработчики) Экспорт"))
			ИЛИ ЭтоБиблиотечнаяПроцедураОписания
				И Код.ЭтоПроцедураОписания
				И (Код.ЗаголовокПроцедуры = БиблиотечныйЗаголовокПроцедуры
						ИЛИ Код.ЗаголовокПроцедуры = ПростойЗаголовокПроцедурыОписания) Тогда
			ВыполненаЗамена = Истина;
			Для Каждого НоваяСтрока Из НовыйТекстПроцедуры Цикл
				НовыйМодуль.ДобавитьСтроку(НоваяСтрока);
			КонецЦикла;
			СтрокаМодуля = ПропуститьСтрокиДо(Модуль, ОкончаниеПроцедуры);
			Продолжить;
		КонецЕсли;
		#КонецОбласти
		
		НовыйМодуль.ДобавитьСтроку(СтрокаМодуля);
		
	КонецЦикла;
	Модуль.Закрыть();
	#КонецЕсли
	
	ИмяПроцедуры = ИмяПроцедуры(Код.ЗаголовокПроцедуры);
	Если УстановленаВерсия Тогда
		Шаблон = НСтр("ru = 'В модуле ""%1"" установлена новая версия ""%2""'");
		ОбщегоНазначенияКлиент.СообщитьПользователю(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, Код.ИмяМодуля, Код.Версия));
	КонецЕсли;
	Если ВыполненаЗамена Тогда
		Шаблон = НСтр("ru = 'В модуле ""%1"" заменена процедура ""%2""'");
		НовыйТекст = НовыйМодуль.ПолучитьТекст();
		ЗаписатьТекстМодуля(НовыйТекст, ПолноеИмяФайла);
		ОбщегоНазначенияКлиент.СообщитьПользователю(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, Код.ИмяМодуля, ИмяПроцедуры));
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Функция ПропуститьСтрокиДо(Модуль, ОкончаниеФрагмента)
	
	СтрокаМодуля = "";
	Пока СтрНайти(СтрокаМодуля, ОкончаниеФрагмента) = 0 Цикл
		СтрокаМодуля = Модуль.ПрочитатьСтроку();
		Если СтрНайти(СокрЛП(СтрокаМодуля), "Процедура") = 1 Тогда
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Возврат СтрокаМодуля;
	
КонецФункции

&НаКлиенте
Функция ТекстФайлаВМассив(ПолноеИмяФайла)
	
	Результат = Новый Массив;
	
	#Если НЕ ВебКлиент Тогда
	Модуль = Новый ЧтениеТекста;
	Модуль.Открыть(ПолноеИмяФайла, "UTF-8");
	СтрокаМодуля = "";
	Пока СтрокаМодуля <> Неопределено Цикл
		СтрокаМодуля = Модуль.ПрочитатьСтроку();
		Если СтрокаМодуля = Неопределено Тогда
			Прервать;
		КонецЕсли;
		Результат.Добавить(СтрокаМодуля);
	КонецЦикла;
	#КонецЕсли
	
	Возврат Результат;
	
КонецФункции

&НаКлиенте
Функция ИмяПроцедуры(ЗаголовокПроцедуры)
	
	ИмяПроцедуры = СтрЗаменить(ЗаголовокПроцедуры, "Процедура", "");
	ИмяПроцедуры = СокрЛП(СтрЗаменить(ИмяПроцедуры, "Экспорт", ""));
	Скобка1 = СтрНайти(ИмяПроцедуры, "(");
	Возврат Лев(ИмяПроцедуры, Скобка1-1);
	
КонецФункции

&НаКлиенте
Процедура ЗаписатьТекстМодуля(ТекстФайла, ПолноеИмяФайла)
	
	ДополнительныеПараметры = Новый Структура;
	ДополнительныеПараметры.Вставить("ПолноеИмяФайла", ПолноеИмяФайла);
	ДополнительныеПараметры.Вставить("ТекстФайла", ТекстФайла);
	#Если НЕ ВебКлиент Тогда
	УдалитьФайлы(ПолноеИмяФайла);
	УдалениеФайлаМодуляЗавершение(ДополнительныеПараметры);
	#КонецЕсли
	
КонецПроцедуры

&НаКлиенте
Процедура УдалениеФайлаМодуляЗавершение(ДополнительныеПараметры)
	
	ПолноеИмяФайла = ДополнительныеПараметры.ПолноеИмяФайла;
	ТекстФайла = ДополнительныеПараметры.ТекстФайла;
	
	#Если НЕ ВебКлиент Тогда
	ЗаписатьBOM = Ложь;
	Поток = Новый ФайловыйПоток(ПолноеИмяФайла, РежимОткрытияФайла.СоздатьНовый);
	РазделительСтрок = Символы.ВК + Символы.ПС;
	ЗаписьТекста = Новый ЗаписьТекста(Поток, КодировкаТекста.UTF8, РазделительСтрок,,ЗаписатьBOM);
	
	ЗаписьТекста.Записать(ТекстФайла);
	ЗаписьТекста.Закрыть();

	Поток.Закрыть();
	#КонецЕсли
	
КонецПроцедуры

&НаКлиенте
Процедура СохранитьСписокОбработчиковТехПроекта()
	
	ИмяФайла = КаталогНастроек() + "tech-project.updaters";
	
	ОбработчикиТехПроекта = ОбработчикиТехническогоПроекта();
	Если ОбработчикиТехПроекта.Количество() > 0 Тогда
		ТекстФайла = СтрСоединить(ОбработчикиТехПроекта, Символы.ПС);
		ЗаписатьФайлНаДиск(ИмяФайла, ТекстФайла);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Функция ОбработчикиТехническогоПроекта()
	
	Отбор = Новый Структура("ТехническийПроект", Истина);
	Обработчики = Объект.ОбработчикиОбновления.Выгрузить(Отбор);
	ОбработчикиТехПроекта = Новый Массив;
	Для Каждого Обработчик Из Обработчики Цикл
		Описание = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1:%2", Обработчик.Идентификатор, Обработчик.Процедура);
		ОбработчикиТехПроекта.Добавить(Описание);
	КонецЦикла;
	
	Возврат ОбработчикиТехПроекта;
	
КонецФункции

&НаКлиенте
Процедура СохранитьВерсиюВКореньКонфигурации()
	
	ПолноеИмяФайла = Объект.КаталогSRC + "Configuration\Configuration.mdo";
	
	#Если НЕ ВебКлиент Тогда
	УстановленаВерсия = Ложь;
	НовыйФайл = Новый ТекстовыйДокумент;
	ТекстФайла = Новый ЧтениеТекста;
	ТекстФайла.Открыть(ПолноеИмяФайла, "UTF-8");
	СтрокаМодуля = "";
	Пока СтрокаМодуля <> Неопределено Цикл

		СтрокаМодуля = ТекстФайла.ПрочитатьСтроку();
		Если СтрокаМодуля = Неопределено Тогда
			Прервать;
		КонецЕсли;
		
		Если СтрНайти(СтрокаМодуля, "<version>") > 0 
			И СтрНайти(СтрокаМодуля,  НоваяВерсияКонфигурации) = 0 Тогда
				УстановленаВерсия = Истина;
				СтрокаМодуля = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("  <version>%1</version>", НоваяВерсияКонфигурации);
		КонецЕсли;
		НовыйФайл.ДобавитьСтроку(СтрокаМодуля);
		
	КонецЦикла;
	
	ТекстФайла = НовыйФайл.ПолучитьТекст();
	Если УстановленаВерсия Тогда
		Шаблон = НСтр("ru = 'Установлена новая версия ""%1"" в корне конфигурации'");
		НовыйТекст = НовыйФайл.ПолучитьТекст();
		ЗаписатьТекстМодуля(НовыйТекст, ПолноеИмяФайла);
		ОбщегоНазначенияКлиент.СообщитьПользователю(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, НоваяВерсияКонфигурации));
	КонецЕсли;
	ЗаписатьФайлНаДиск(ПолноеИмяФайла, ТекстФайла);
	#КонецЕсли
	
КонецПроцедуры

&НаКлиенте
Функция ЗаписатьФайлНаДиск(ПолноеИмяФайла, ТекстФайла)
	
	#Если НЕ ВебКлиент Тогда
	ЗаписатьBOM = Ложь;
	УдалитьФайлы(ПолноеИмяФайла);
	Поток = Новый ФайловыйПоток(ПолноеИмяФайла, РежимОткрытияФайла.СоздатьНовый);
	РазделительСтрок = Символы.ВК + Символы.ПС;
	ЗаписьТекста = Новый ЗаписьТекста(Поток, КодировкаТекста.UTF8, РазделительСтрок, , ЗаписатьBOM);
	
	ЗаписьТекста.Записать(ТекстФайла);
	ЗаписьТекста.Закрыть();
	
	Поток.Закрыть();
	#КонецЕсли
	
	Возврат ПолноеИмяФайла;
	
КонецФункции

#КонецОбласти

#Область РедактированиеОбработчика

&НаКлиенте
Процедура ОткрытьРедакторОписанияОбработчика(СсылкаОбработчика, НоваяСтрока = Ложь, ИсточникКопирования = "")
	
	ПараметрыПодключаемогоОбработчика = Новый Структура;
	ПараметрыПодключаемогоОбработчика.Вставить("СсылкаОбработчика", СсылкаОбработчика);
	ПараметрыПодключаемогоОбработчика.Вставить("НоваяСтрока", НоваяСтрока);
	ПараметрыПодключаемогоОбработчика.Вставить("ИсточникКопирования", ИсточникКопирования);
	
	ПодключитьОбработчикОжидания("Подключаемый_ОткрытьРедакторОписанияОбработчика", 0.1, Истина);
	
КонецПроцедуры
	
&НаКлиенте
Процедура Подключаемый_ОткрытьРедакторОписанияОбработчика()
	
	СсылкаОбработчика = ПараметрыПодключаемогоОбработчика.СсылкаОбработчика;
	НоваяСтрока = ПараметрыПодключаемогоОбработчика.НоваяСтрока;
	ИсточникКопирования = ПараметрыПодключаемогоОбработчика.ИсточникКопирования;
	
	АдресДанных = ПоместитьДанныеОбработчикаВХранилище(СсылкаОбработчика,,ИсточникКопирования);
	ПараметрыФормы = Новый Структура("АдресОбработчика, НоваяСтрока", АдресДанных, НоваяСтрока);
	ПараметрыФормы.Вставить("ЗапускИзКонфигурации", ЗапускИзКонфигурации);
	
	ДополнительныеПараметры = Новый Структура("Ссылка", СсылкаОбработчика);
	ОбработчикЗакрытияФормы = Новый ОписаниеОповещения("ЗавершениеРедактированияОбработчика", ЭтотОбъект, ДополнительныеПараметры);
	
	ИмяФормыОбработчика = "Обработка.ОписаниеОбработчиковОбновления.Форма.ФормаОбработчика";
	Если НЕ ЗапускИзКонфигурации Тогда
		ИмяФормыОбработчика = "ВнешняяОбработка.ОписаниеОбработчиковОбновления.Форма.ФормаОбработчика";
	КонецЕсли;
	
	ОткрытьФорму(ИмяФормыОбработчика,
		ПараметрыФормы,
		ЭтотОбъект,
		УникальныйИдентификатор,
		,
		,
		ОбработчикЗакрытияФормы,
		РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
	
КонецПроцедуры

&НаСервере
Функция ПоместитьДанныеОбработчикаВХранилище(СсылкаОбработчика, Адрес = Неопределено, ИсточникКопирования = Неопределено)
	
	ТабЧасти = Новый Структура;
	Данные = Новый Структура("ТабличныеЧасти", ТабЧасти);
	
	Данные.Вставить("МодулиПодсистем", МодулиПодсистем);
	
	Отбор = Новый Структура("Ссылка", СсылкаОбработчика);
	Данные.ТабличныеЧасти.Вставить("ОбработчикиОбновления", Объект.ОбработчикиОбновления.Выгрузить(Отбор));
	Если ЗначениеЗаполнено(ИсточникКопирования) Тогда
		ДобавитьОбъектыИсходногоОбработчика(Данные, ИсточникКопирования);
		
	Иначе
		ТабЧасти.Вставить("ЧитаемыеОбъекты", Объект.ЧитаемыеОбъекты.Выгрузить(Отбор));
		ТабЧасти.Вставить("ИзменяемыеОбъекты", Объект.ИзменяемыеОбъекты.Выгрузить(Отбор));
		ТабЧасти.Вставить("БлокируемыеОбъекты", Объект.БлокируемыеОбъекты.Выгрузить(Отбор));
		ТабЧасти.Вставить("ПриоритетыВыполнения", Объект.ПриоритетыВыполнения.Выгрузить(Отбор));
		ТабЧасти.Вставить("ЧтениеНизкогоПорядка", Объект.ЧтениеНизкогоПорядка.Выгрузить(Отбор));
	
		Отбор = Новый Структура("ОбработчикПисатель", СсылкаОбработчика);
		ТабЧасти.Вставить("КонфликтыОбработчиков", Объект.КонфликтыОбработчиков.Выгрузить(Отбор));
		
		Отбор = Новый Структура("ОбработчикЧитательИлиПисатель2", СсылкаОбработчика);
		ЕщеКонфликты = Объект.КонфликтыОбработчиков.Выгрузить(Отбор);
		ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(ЕщеКонфликты, ТабЧасти.КонфликтыОбработчиков);
		
	КонецЕсли;
	
	Если Адрес = Неопределено Тогда
		Адрес = ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор);
	Иначе
		ПоместитьВоВременноеХранилище(Данные, Адрес);
	КонецЕсли;
	
	Возврат Адрес;
	
КонецФункции

// Параметры:
//   Данные - Структура:
//   * МодулиПодсистем - Массив из Строка
//   * ТабличныеЧасти - КлючИЗначение:
//    **ОбработчикиОбновления - ТаблицаЗначений:
//     *** Ссылка - Строка
//   ИсточникКопирования - Неопределено
//                       - Строка
//
&НаСервере
Процедура ДобавитьОбъектыИсходногоОбработчика(Данные, ИсточникКопирования)
	
	ТабличныеЧасти = Новый Массив;
	ТабличныеЧасти.Добавить("ЧитаемыеОбъекты");
	ТабличныеЧасти.Добавить("ИзменяемыеОбъекты");
	ТабличныеЧасти.Добавить("БлокируемыеОбъекты");
	
	Отбор = Новый Структура("Ссылка", ИсточникКопирования);
	Обработчик = Данные.ТабличныеЧасти.ОбработчикиОбновления[0];
	НоваяСсылка = Обработчик.Ссылка;
	Для Каждого ИмяТабЧасти Из ТабличныеЧасти Цикл
		тз = Объект[ИмяТабЧасти].Выгрузить(Отбор);
		тз.ЗаполнитьЗначения(НоваяСсылка, "Ссылка");
		Данные.ТабличныеЧасти.Вставить(ИмяТабЧасти, тз);
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Функция ОбновитьДанныеОбработчика(АдресОбработчика)
	
	Обработка = ОбъектОбработки();
	Данные = ПолучитьИзВременногоХранилища(АдресОбработчика); // см. ДобавитьОбъектыИсходногоОбработчика.Данные
	
	НовоеОписание = Данные.ТабличныеЧасти.ОбработчикиОбновления[0];
	Модифицированность = НовоеОписание.Изменен;
	
	НовоеОписание.ВерсияЧислом = Обработка.ВерсияЧислом(НовоеОписание.Версия);
	НомераВерсии = СтрРазделить(НовоеОписание.Версия, ".");
	НомераВерсии.Удалить(0);
	НовоеОписание.РедакцияЧислом = Обработка.ВерсияЧислом(НомераВерсии);
	
	ОписаниеОбработчика = Обработка.ОбработчикиОбновления.Найти(НовоеОписание.Ссылка, "Ссылка");
	Если ОписаниеОбработчика <> Неопределено Тогда
		
		ЗаполнитьЗначенияСвойств(ОписаниеОбработчика, НовоеОписание);
		Если МодулиПодсистем <> Неопределено И НовоеОписание.Подсистема <> "" Тогда
			ОписаниеОбработчика.ИмяОсновногоСерверногоМодуля = МодулиПодсистем[НовоеОписание.Подсистема];
			ОписаниеОбработчика.ИмяБиблиотеки = СтрЗаменить(ОписаниеОбработчика.ИмяОсновногоСерверногоМодуля, "ОбновлениеИнформационнойБазы", "");
		КонецЕсли;
		Имена = СтрРазделить(ОписаниеОбработчика.Процедура, ".");
		Имена.Удалить(Имена.ВГраница());
		ОписаниеОбработчика.ИмяОбъекта = СтрСоединить(Имена, ".");
		
		ИнверсныйПорядок = Обработка.ОбратныйПорядок();
		Отбор = Новый Структура("Ссылка", ОписаниеОбработчика.Ссылка);
		Для Каждого ТабличнаяЧасть Из Данные.ТабличныеЧасти Цикл
			
			Если ТабличнаяЧасть.Ключ <> "ОбработчикиОбновления" Тогда
				НайденныеСтроки = Обработка[ТабличнаяЧасть.Ключ].НайтиСтроки(Отбор);
				Для Каждого СтрокаКУдалению Из НайденныеСтроки Цикл
					Обработка[ТабличнаяЧасть.Ключ].Удалить(СтрокаКУдалению);
				КонецЦикла;
				
				Для Каждого Запись Из ТабличнаяЧасть.Значение Цикл
					НоваяСтрока = Обработка[ТабличнаяЧасть.Ключ].Добавить();
					ЗаполнитьЗначенияСвойств(НоваяСтрока, Запись,,"НомерСтроки");
					Если ТабличнаяЧасть.Ключ = "ПриоритетыВыполнения" Тогда
						ИнвертироватьПорядок(Обработка, Запись, ИнверсныйПорядок)
					КонецЕсли;
				КонецЦикла;
			КонецЕсли;
			
		КонецЦикла;
		ОбновитьСведенияОКонфликтахОбработчиков(Обработка);
		ЗначениеВРеквизитФормы(Обработка, "Объект");
		
		Отбор = Новый Структура("Ссылка", НовоеОписание.Ссылка);
		НайденныеСтроки = Объект.ОбработчикиОбновления.НайтиСтроки(Отбор);
		Если НайденныеСтроки.Количество() > 0 Тогда
			НайденныеСтроки[0].НоваяСтрока = Ложь;
			Элементы.ОбработчикиОбновления.ТекущаяСтрока = НайденныеСтроки[0].ПолучитьИдентификатор();
			ИсходнаяТекущаяСтрока = Элементы.ОбработчикиОбновления.ТекущаяСтрока;
		КонецЕсли;
		
		ОбновитьОтборыОбработчиков();
		
	КонецЕсли;
	
	Возврат НовоеОписание.Ссылка;
	
КонецФункции

&НаСервере
Процедура ИнвертироватьПорядок(Обработка, Запись, ИнверсныйПорядок)
	
	Отбор = Новый Структура("Ссылка, Обработчик2");
	Отбор.Ссылка = Запись.Обработчик2;
	Отбор.Обработчик2 = Запись.Ссылка;
	НайденныеПриоритеты = Обработка["ПриоритетыВыполнения"].НайтиСтроки(Отбор);
	Для Каждого Приоритет Из НайденныеПриоритеты Цикл
		Если НЕ ПустаяСтрока(Запись.Порядок) Тогда
			НовыйПорядок = ИнверсныйПорядок[Запись.Порядок];
			Если НовыйПорядок <> Приоритет.Порядок Тогда
				Приоритет.Порядок = НовыйПорядок;
				Приоритет.ЗаданПорядокВыполнения = Истина;
				Отбор = Новый Структура("Ссылка", Запись.Обработчик2);
				НайденныеОбработчики = Обработка["ОбработчикиОбновления"].НайтиСтроки(Отбор);
				Если НайденныеОбработчики.Количество() > 0 Тогда
					НайденныеОбработчики[0].Изменен = Истина;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Процедура ОбновитьДанныеОКонфликтахОбработчика(АдресОбработчика)
	
	СсылкаОбработчика = ОбновитьДанныеОбработчика(АдресОбработчика);
	ПоместитьДанныеОбработчикаВХранилище(СсылкаОбработчика, АдресОбработчика);
	
КонецПроцедуры

&НаСервере
Процедура ПриоритетыКонфликтовЧитаемыхИлиДвойнойЗаписи(ПриоритетыВыполнения, Конфликты)
	
	ПриоритетыОбработчика1 = ПриоритетыВыполнения.Скопировать();
	ПриоритетыВыполнения.Очистить();
	
	Для Каждого ПриоритетОбработчика1 Из ПриоритетыОбработчика1 Цикл
		ЧитаемыеДанныеИзменяютсяДругими = Конфликты.Найти(ПриоритетОбработчика1.Процедура2, "ПроцедураПисатель") <> Неопределено;
		РазрабатываемаяБиблиотека_ИзменяетЧитаемыеДанные = РазрабатываемыеПодсистемы.Найти(ПриоритетОбработчика1.Подсистема2) <> Неопределено;
		РучнойПорядок = ПриоритетОбработчика1.Порядок <> ПриоритетОбработчика1.ПорядокАвто;
		Если (ЧитаемыеДанныеИзменяютсяДругими ИЛИ НЕ РазрабатываемаяБиблиотека_ИзменяетЧитаемыеДанные) И РучнойПорядок Тогда
			НоваяСтрока = ПриоритетыВыполнения.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, ПриоритетОбработчика1);
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область ПостроениеОчереди

&НаСервере
Функция ПостроитьОчередьНаСервере()
	
	ИтерацииОбновления = ОбновлениеИнформационнойБазыСлужебный.ИтерацииОбновления();
	ОбновлениеИнформационнойБазыПереопределяемый.ПередФормированиеСпискаОтложенныхОбработчиков(ИтерацииОбновления);
	
	Обработка = ОбъектОбработки();
	ВсеХорошо = Обработка.ПостроитьОчередь();
	ЗначениеВРеквизитФормы(Обработка, "Объект");
	
	ОбновитьДанныеФормы(Обработка);
	
	Возврат ВсеХорошо;
	
КонецФункции

#КонецОбласти

#Область ОбнаружениеКонфликтов

&НаСервере
Процедура ОбновитьСведенияОКонфликтахОбработчиков(Обработка)
	
	НовоеОписание = Обработка.ОбновитьСведенияОКонфликтахОбработчиков();
	ЗаполнитьБыстрыеОтборы(НовоеОписание);
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьБыстрыеОтборы(Знач ОписаниеОбработчиков = Неопределено)
	
	Если ОписаниеОбработчиков = Неопределено Тогда
		ОписаниеОбработчиков = Объект.ОбработчикиОбновления.Выгрузить();
	КонецЕсли;
	
	МассивСтрок = Новый Массив;
	ПрочиеБыстрыеОтборы.Очистить();
	
	ДобавитьБыстрыйОтбор(ОписаниеОбработчиков, МассивСтрок, "СтатусПроблемы", СтатусНеобходимАнализ, "НеобходимАнализ", ЦветаСтиля.ЦветОсобогоТекста);
	ДобавитьБыстрыйОтбор(ОписаниеОбработчиков, МассивСтрок, "ЧтениеНизкогоПорядка", СтатусЧтениеНизкогоПорядка, "ЧтениеНизкогоПорядка", ЦветаСтиля.ЦветОсобогоТекста);
	ДобавитьБыстрыйОтбор(ОписаниеОбработчиков, МассивСтрок, "ИзмененаПроцедураПроверки", СтатусИзмененаПроцедураПроверки, "ИзмененаПроцедураПроверки", WebЦвета.Золотистый);
	ДобавитьБыстрыйОтбор(ОписаниеОбработчиков, МассивСтрок, "РежимВыполнения", НСтр("ru = 'Отложенно'"), "Отложенно");
	ДобавитьБыстрыйОтбор(ОписаниеОбработчиков, МассивСтрок, "РежимВыполнения", НСтр("ru = 'Монопольно'"), "Монопольно");
	ДобавитьБыстрыйОтбор(ОписаниеОбработчиков, МассивСтрок, "РежимВыполнения", НСтр("ru = 'Оперативно'"), "Оперативно");
	ДобавитьБыстрыйОтбор(ОписаниеОбработчиков, МассивСтрок, "ТехническийПроект", НСтр("ru = 'Тех.проект'"), "ТехническийПроект");
	
	ДобавитьПрочийБыстрыйОтбор(ОписаниеОбработчиков, "РежимВыполненияОтложенныхОбработчиков", НСтр("ru = 'Параллельно'"), "Параллельно");
	ДобавитьПрочийБыстрыйОтбор(ОписаниеОбработчиков, "РежимВыполненияОтложенныхОбработчиков", НСтр("ru = 'Последовательно'"), "Последовательно");
	ДобавитьПрочийБыстрыйОтбор(ОписаниеОбработчиков, "НачальноеЗаполнение", НСтр("ru = 'Начальное заполнение'"), "НачальноеЗаполнение");
	ДобавитьПрочийБыстрыйОтбор(ОписаниеОбработчиков, "ВыполнятьВГруппеОбязательных", НСтр("ru = 'Обязательный'"), "Обязательный");
	ДобавитьПрочийБыстрыйОтбор(ОписаниеОбработчиков, "Многопоточный", НСтр("ru = 'Многопоточный'"), "Многопоточный");
	ДобавитьПрочийБыстрыйОтбор(ОписаниеОбработчиков, "ЗаписьЧитаемых", НСтр("ru = 'Запись читаемых'"), "ЗаписьЧитаемых");
	ДобавитьПрочийБыстрыйОтбор(ОписаниеОбработчиков, "ПовторнаяЗапись", НСтр("ru = 'Повторная запись'"), "ПовторнаяЗапись");
	
	ТекстСтатуса = НСтр("ru = 'Прочие'");
	СтрокаГиперссылки = Новый ФорматированнаяСтрока(
		ТекстСтатуса,
		, 
		ЦветаСтиля.ЦветТекстаКнопки, ,
		"Прочие");
	МассивСтрок.Добавить(СтрокаГиперссылки);
	МассивСтрок.Добавить("  ");
	
	ТекстСтатуса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1 (%2)", НСтр("ru = 'Все'"), ОписаниеОбработчиков.Количество());
	СтрокаГиперссылки = Новый ФорматированнаяСтрока(
		ТекстСтатуса, 
    	, 
		ЦветаСтиля.ЦветТекстаКнопки, ,
		"Все");
		
	МассивСтрок.Добавить(СтрокаГиперссылки);
	
	Элементы.БыстрыеОтборы.Заголовок = Новый ФорматированнаяСтрока(МассивСтрок);
	
КонецПроцедуры

&НаСервере
Процедура ДобавитьБыстрыйОтбор(ОписаниеОбработчиков, МассивСтрок, ИмяПоляОтбора, Знач ЗначениеОтбора, ИдентификаторСсылки, Знач Цвет = Неопределено)
	
	Если Цвет = Неопределено Тогда
		Цвет = ЦветаСтиля.ЦветТекстаКнопки;
	КонецЕсли;
	
	ПредставлениеОтбора = ЗначениеОтбора;
	
	Для Каждого ТипПоля Из ОписаниеОбработчиков.Колонки[ИмяПоляОтбора].ТипЗначения.Типы() Цикл
		Если ТипПоля = Тип("Булево") Тогда
			ЗначениеОтбора = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Отбор = Новый Структура(ИмяПоляОтбора, ЗначениеОтбора);
	СтрокиОтбора = ОписаниеОбработчиков.Скопировать(Отбор);
	Если СтрокиОтбора.Количество() > 0 Тогда
		
		ТекстСтатуса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1 (%2)", ПредставлениеОтбора, СтрокиОтбора.Количество());
		СтрокаГиперссылки = Новый ФорматированнаяСтрока(
			ТекстСтатуса,
			,
			Цвет, ,
			ИдентификаторСсылки);
		
		МассивСтрок.Добавить(СтрокаГиперссылки);
		МассивСтрок.Добавить("  ");
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ДобавитьПрочийБыстрыйОтбор(ОписаниеОбработчиков, ИмяПоляОтбора, Знач ЗначениеОтбора, ИдентификаторСсылки)
	
	ПредставлениеОтбора = ЗначениеОтбора;
	Для Каждого ТипПоля Из ОписаниеОбработчиков.Колонки[ИмяПоляОтбора].ТипЗначения.Типы() Цикл
		Если ТипПоля = Тип("Булево") Тогда
			ЗначениеОтбора = Истина;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Отбор = Новый Структура(ИмяПоляОтбора, ЗначениеОтбора);
	СтрокиОтбора = ОписаниеОбработчиков.Скопировать(Отбор);
	Если СтрокиОтбора.Количество() > 0 Тогда
		ТекстСтатуса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1 (%2)", ПредставлениеОтбора, СтрокиОтбора.Количество());
		ПрочиеБыстрыеОтборы.Добавить(ИдентификаторСсылки, ТекстСтатуса);
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ГенерацияКода

&НаКлиенте
Процедура ПоказатьТекстыОписанияОбработчиковОбновления(ПараметрыГенерацииКода)
	
	ТекстыМодулей = ПолучитьТекстыМодулей(ПараметрыГенерацииКода);
	Для Каждого КодМодуля Из ТекстыМодулей Цикл
		ТекстовыйДокумент = Новый ТекстовыйДокумент;
		ТекстовыйДокумент.УстановитьТекст(КодМодуля.ТекстПроцедуры);
		ТекстовыйДокумент.Показать(КодМодуля.ИмяМодуля);
	КонецЦикла;
	Элементы.ГруппаНастройкиЗагрузкиВыгрузки.Скрыть();
	Модифицированность = Ложь;
	
КонецПроцедуры

&НаКлиенте
Функция ПолучитьТекстыМодулей(ПараметрыГенерацииКода = Неопределено)
	
	Если ПараметрыГенерацииКода = Неопределено Тогда
		ПараметрыГенерацииКода = НовыеПараметрыГенерацииКода();
	КонецЕсли;
	Настройки = Новый Структура("ПараметрыГенерацииКода", ПараметрыГенерацииКода);
	
	ИмяФайла = КаталогНастроек() + "cut_tags.yml";
	Файл = Новый Файл(ИмяФайла);
	Если Файл.Существует() Тогда
		ОписаниеТэгов = ПрочитатьФайлYaml(ИмяФайла);
		Если ОписаниеТэгов["configurations"] <> Неопределено Тогда
			ПолучитьОбъектыПодсистем(ОписаниеТэгов["configurations"]);
			ВсеОбъекты = ПолучитьВсеОбъектыИсходнойКонфигурации();
			ОпределитьТэгиДляОбъектовНеВходящихВКонфигурацию(ОписаниеТэгов);
			Настройки.Вставить("ОписаниеТэгов", ОписаниеТэгов);
			Настройки.Вставить("ВсеОбъекты", ВсеОбъекты);
		КонецЕсли;
	КонецЕсли;
	АдресНастроек = ПоместитьВоВременноеХранилище(Настройки, УникальныйИдентификатор);
	
	Если ПараметрыГенерацииКода.ОписаниеВОбщемМодуле Тогда
		Возврат ОписанияОбработчиковПоМодулямОбновления(АдресНастроек);
	Иначе
		Возврат ОписанияОбработчиковПоМодулямМенеджеров(АдресНастроек);
	КонецЕсли;
	
КонецФункции

&НаКлиенте
Функция НовыеПараметрыГенерацииКода()
	
	Результат = Новый Структура;
	Результат.Вставить("ОписаниеВОбщемМодуле", Ложь);
	Результат.Вставить("ТолькоИзмененные", Истина);
	Результат.Вставить("ТолькоВыделенные", Ложь);
	Результат.Вставить("ОбновитьОчередь", Истина);
	Результат.Вставить("ОбновитьСписокВызовов", Истина);
	Возврат Результат;
	
КонецФункции

#Область ПоМодулямОбновления

&НаСервере
Функция ОписанияОбработчиковПоМодулямОбновления(АдресНастроек)
	
	Настройки = ПолучитьИзВременногоХранилища(АдресНастроек);
	
	ТекстыМодулей = Новый Массив;
	Если НЕ ПостроитьОчередьНаСервере() Тогда
		Возврат ТекстыМодулей;
	КонецЕсли;
	
	ОписаниеКонфигураций = Новый Соответствие;
	ИменаКонфигураций = Новый Массив;
	РазметкаКода = Новый Структура("УстановитьТэги", Ложь);
	РазметкаКода.Вставить("ЭтоМодульМенеджера", Ложь);
	РазметкаКода.Вставить("ДобавитьОбластьОписания", Истина);
	РазметкаКода.Вставить("ЭтоПроцедураОписания", Ложь);
	Если Настройки.Свойство("ОписаниеТэгов") Тогда
		ОписаниеКонфигураций = Настройки.ОписаниеТэгов["configurations"];
		Тэги = ПолучитьСведенияОТегахВырезки(Настройки);
		ИменаКонфигураций = Тэги.БиблиотекиВПорядкеВложенности;
		РазметкаКода.УстановитьТэги = Истина;
		РазметкаКода.Вставить("Тэги", Тэги);
	Иначе
		ЗаполнитьОписание(ОписаниеКонфигураций, ИменаКонфигураций);
	КонецЕсли;
	
	ВерсииМодулей = ОписаниеВерсийМодулей();
	Для Каждого ИмяКонфигурации Из ИменаКонфигураций Цикл
		
		ОписаниеКонфигурации = ОписаниеКонфигураций[ИмяКонфигурации];
		ИмяОсновногоСерверногоМодуля = ОписаниеКонфигурации["module"];
		Если ИмяОсновногоСерверногоМодуля = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если РазрабатываемыеПодсистемы.Найти(ОписаниеКонфигурации["name"]) = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если РазметкаКода.УстановитьТэги Тогда
			РазметкаКода.Вставить("ИмяКонфигурации", ИмяКонфигурации);
			РазметкаКода.Вставить("ИмяМодуля", ИмяОсновногоСерверногоМодуля);
			РазметкаКода.Вставить("ИмяПроцедуры", "ПриДобавленииОбработчиковОбновления");
			РазметкаКода.Вставить("ЭтоПроцедураОписания", Ложь);
			РазметкаКода.Вставить("МодульЛокализации", ОписаниеКонфигурации["localization"] <> Неопределено);
			Если РазметкаКода.МодульЛокализации Тогда
				Если ОписаниеКонфигурации["outTags"].Количество() > 0 Тогда
					РазметкаКода.Вставить("ТэгиЛокализации", ОписаниеКонфигурации["outTags"][0]);
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		
		Отбор = Новый Структура("РежимВыполненияОтложенныхОбработчиков", "Параллельно");
		Отбор.Вставить("ИмяОсновногоСерверногоМодуля", ИмяОсновногоСерверногоМодуля);
		ОбработчикиМодуля = Объект.ОбработчикиОбновления.Выгрузить(Отбор);
		
		Если ОбработчикиМодуля.Количество() = 0 Тогда
			Продолжить;
		КонецЕсли;
		
		ОбработчикиМодуля.Сортировать("Процедура");
		МодулиОбработчиковОбновления(ОбработчикиМодуля, РазметкаКода);
		Если РазметкаКода.УстановитьТэги Тогда
			РазметкаКода.Тэги.Вставить("ПоОбработчикам", ОбработчикиМодуля);
		КонецЕсли;
		ТекстОбработчиков = ТекстОбработчиков(ОбработчикиМодуля, РазметкаКода);
		
		Если РазметкаКода.УстановитьТэги И РазметкаКода.МодульЛокализации Тогда
			ТэгБиблиотеки = Тэги.ПоБиблиотекам.Найти(ИмяКонфигурации);
			Если ТэгБиблиотеки <> Неопределено Тогда
				ТэгЛокализации = Тэги.Описание[ТэгБиблиотеки.Тэг]; // см. ОписаниеТэга
				Если ТэгЛокализации <> Неопределено Тогда
					Шаблон = "%1
					|%2
					|%3";
					ТекстОбработчиков = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ТэгЛокализации.Начало, ТекстОбработчиков, ТэгЛокализации.Конец);
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		
		ТекстПроцедуры = 
		"Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
		|
		|"+ ТекстОбработчиков +"
		|
		|КонецПроцедуры";
		
		КодМодуля = ОписаниеКодаМодуля(ИмяОсновногоСерверногоМодуля, ТекстПроцедуры);
		КодМодуля.ПутьМодуля = "CommonModules\" + ИмяОсновногоСерверногоМодуля + "\Module.bsl";
		ДобавитьВерсиюМодуля(ВерсииМодулей, ОбработчикиМодуля);
		ТекстыМодулей.Добавить(КодМодуля);
		
	КонецЦикла;
	
	Если ВерсииМодулей.Количество() > 0 Тогда
		УстановитьВерсиюМодуля(ТекстыМодулей, ВерсииМодулей);
	КонецЕсли;
	
	Возврат ТекстыМодулей;
	
КонецФункции

#КонецОбласти

#Область ПоМодулямОбъектовОбновления

&НаСервере
Функция ОписанияОбработчиковПоМодулямМенеджеров(АдресНастроек)
	
	ТекстыМодулей = Новый Массив;
	
	Настройки = ПолучитьИзВременногоХранилища(АдресНастроек);
	ПараметрыГенерацииКода = Настройки.ПараметрыГенерацииКода;
	ТолькоИзмененные = ПараметрыГенерацииКода.ТолькоИзмененные;
	ТолькоВыделенные = ПараметрыГенерацииКода.ТолькоВыделенные;
	ОбновитьСписокВызовов = ПараметрыГенерацииКода.ОбновитьСписокВызовов;
	ОбновитьОчередь = ПараметрыГенерацииКода.ОбновитьОчередь;
	
	ВыделенныеОбработчики = Новый Массив;
	Если ТолькоВыделенные Тогда
		ВыделенныеОбработчики = ВыделенныеОбработчики();
	КонецЕсли;
	
	Если НЕ ТолькоВыделенные И ОбновитьОчередь И НЕ ПостроитьОчередьНаСервере() Тогда
		Возврат ТекстыМодулей;
	КонецЕсли;
	
	ВсеИменаКонфигураций = Новый Соответствие;
	ОписаниеКонфигураций = Новый Соответствие;
	ИменаКонфигураций = Новый Массив;
	РазметкаКода = Новый Структура("УстановитьТэги, ЭтоМодульМенеджера", Ложь, Ложь);
	Если Настройки.Свойство("ОписаниеТэгов") Тогда
		ОписаниеКонфигураций = Настройки.ОписаниеТэгов["configurations"];
		Тэги = ПолучитьСведенияОТегахВырезки(Настройки);
		ИменаКонфигураций = Тэги.БиблиотекиВПорядкеВложенности;
		РазметкаКода.УстановитьТэги = Истина;
		РазметкаКода.Вставить("Тэги", Тэги);
	Иначе
		ЗаполнитьОписание(ОписаниеКонфигураций, ИменаКонфигураций);
	КонецЕсли;
	
	ВерсииМодулей = ОписаниеВерсийМодулей();
	
	#Область СформироватьСпискиМодулейМенеджеров
	ВсеМодулиОбработчиков = Неопределено;
	ОбработчикиКОписанию = Неопределено;
	Для Каждого ИмяКонфигурации Из ИменаКонфигураций Цикл
		
		ОписаниеКонфигурации = ОписаниеКонфигураций[ИмяКонфигурации];
		ИмяОсновногоСерверногоМодуля = ОписаниеКонфигурации["module"];
		Если ИмяОсновногоСерверногоМодуля = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если РазрабатываемыеПодсистемы.Найти(ОписаниеКонфигурации["name"]) = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если РазметкаКода.УстановитьТэги Тогда
			РазметкаКода.Вставить("ИмяКонфигурации", ИмяКонфигурации);
			РазметкаКода.Вставить("ИмяМодуля", ИмяОсновногоСерверногоМодуля);
			РазметкаКода.Вставить("МодульЛокализации", ОписаниеКонфигурации["localization"] <> Неопределено);
			Если РазметкаКода.МодульЛокализации Тогда
				Если ОписаниеКонфигурации["outTags"].Количество() > 0 Тогда
					РазметкаКода.Вставить("ТэгиЛокализации", ОписаниеКонфигурации["outTags"][0]);
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
		ИмяБиблиотеки = СтрЗаменить(ИмяОсновногоСерверногоМодуля, "ОбновлениеИнформационнойБазы", "");
		
		Отбор = Новый Структура("РежимВыполненияОтложенныхОбработчиков", "Параллельно");
		Отбор.Вставить("ИмяОсновногоСерверногоМодуля", ИмяОсновногоСерверногоМодуля);
		ОбработчикиМодуля = Объект.ОбработчикиОбновления.Выгрузить(Отбор);
		
		Если ОбработчикиМодуля.Количество() = 0 Тогда
			Продолжить;
		КонецЕсли;
		ВсеИменаКонфигураций.Вставить(ИмяБиблиотеки, ИмяКонфигурации);
		
		КодМодуля = ОписаниеКодаМодуля(ИмяОсновногоСерверногоМодуля);
		ДобавитьВерсиюМодуля(ВерсииМодулей, ОбработчикиМодуля);
		ОбработчикиМодуля.Сортировать("Процедура");
		
		МодулиОбработчиков = МодулиОбработчиковОбновления(ОбработчикиМодуля, РазметкаКода, ВыделенныеОбработчики);
		Если РазметкаКода.УстановитьТэги Тогда
			ЗаполнитьТэгиМодулейПоПодсистемам(МодулиОбработчиков, РазметкаКода);
		КонецЕсли;
		
		Если ВсеМодулиОбработчиков = Неопределено Тогда
			ВсеМодулиОбработчиков = МодулиОбработчиков;
		Иначе
			ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(МодулиОбработчиков, ВсеМодулиОбработчиков);
		КонецЕсли;
		
		Если ОбработчикиКОписанию = Неопределено Тогда
			ОбработчикиКОписанию = ОбработчикиМодуля;
		Иначе
			ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(ОбработчикиМодуля, ОбработчикиКОписанию);
		КонецЕсли;
		
	КонецЦикла;
	#КонецОбласти
	
	#Область ДополнимВыделенныеОбработчикиДругихБиблиотек
	Если ВыделенныеОбработчики.Количество() > 0 И (ВсеМодулиОбработчиков = Неопределено ИЛИ ВсеМодулиОбработчиков.Количество() = 0) Тогда
		Для Каждого Выделенный Из ВыделенныеОбработчики Цикл
			ОбработчикиМодуля = Объект.ОбработчикиОбновления.Выгрузить(Новый Структура("Ссылка", Выделенный));
			Если ОбработчикиМодуля.Количество() = 0 Тогда
				Продолжить;
			КонецЕсли;
			МодулиОбработчиков = МодулиОбработчиковОбновления(ОбработчикиМодуля, РазметкаКода, ВыделенныеОбработчики);
			Если РазметкаКода.УстановитьТэги Тогда
				ЗаполнитьТэгиМодулейПоПодсистемам(МодулиОбработчиков, РазметкаКода);
			КонецЕсли;
			Если ВсеМодулиОбработчиков = Неопределено Тогда
				ВсеМодулиОбработчиков = МодулиОбработчиков;
			Иначе
				ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(МодулиОбработчиков, ВсеМодулиОбработчиков);
			КонецЕсли;
			
			Если ОбработчикиКОписанию = Неопределено Тогда
				ОбработчикиКОписанию = ОбработчикиМодуля;
			Иначе
				ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(ОбработчикиМодуля, ОбработчикиКОписанию);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	#КонецОбласти
	
	#Область ДополнимКонфликтующиеОбработчики
	Если РазметкаКода.УстановитьТэги И НЕ ТолькоВыделенные Тогда
		ИзмененныеОбработчики = Объект.ОбработчикиОбновления.Выгрузить(Новый Структура("Изменен", Истина)).ВыгрузитьКолонку("Ссылка");
		Если ВыделенныеОбработчики.Количество() > 0 Тогда
			ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ИзмененныеОбработчики, ВыделенныеОбработчики, Истина);
		КонецЕсли;
		Для Каждого Измененный Из ИзмененныеОбработчики Цикл
			КонфликтыОбработчика = Объект.КонфликтыОбработчиков.Выгрузить(Новый Структура("ОбработчикПисатель", Измененный));
			КонфликтующиеОбработчики = ВсеМодулиОбработчиков.СкопироватьКолонки();
			Для Каждого Конфликт Из КонфликтыОбработчика Цикл
				Обработчик = ОбработчикиКОписанию.Найти(Конфликт.ОбработчикЧитательИлиПисатель2, "Ссылка");
				Если Обработчик <> Неопределено Тогда
					Буфер = КонфликтующиеОбработчики.СкопироватьКолонки();
					НовыйМодуль = Буфер.Добавить();
					ЗаполнитьЗначенияСвойств(НовыйМодуль, Обработчик);
					НовыйМодуль.Изменен = ТолькоИзмененные;
					РазметкаКода.ИмяКонфигурации = ВсеИменаКонфигураций[Обработчик.ИмяБиблиотеки];
					ЗаполнитьТэгиМодулейПоПодсистемам(Буфер, РазметкаКода);
					ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(Буфер, КонфликтующиеОбработчики);
				КонецЕсли;
			КонецЦикла;
			ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(КонфликтующиеОбработчики, ВсеМодулиОбработчиков);
		КонецЦикла;
	КонецЕсли;
	#КонецОбласти
	
	Если ВсеМодулиОбработчиков = Неопределено Тогда
		Возврат ТекстыМодулей;
	КонецЕсли;
	
	#Область СформироватьПроцедурыОписаниеОбработчиковОбновления
	Если РазметкаКода.УстановитьТэги Тогда
		РазметкаКода.Тэги.Вставить("ПоОбработчикам", ОбработчикиКОписанию);
	КонецЕсли;
	РазметкаКода.Вставить("ДобавитьОбластьОписания", Ложь);
	РазметкаКода.Вставить("ИмяПроцедуры", "ПриДобавленииОбработчиковОбновления");
	РазметкаКода.Вставить("ЭтоПроцедураОписания", Истина);
		
	ВсеМодулиОбработчиков.Свернуть("МодульОбработчика,ИмяОбъекта,ВнешниеТэги", "Изменен");
	ВсеМодулиОбработчиков.Сортировать("МодульОбработчика");
	
	ТипСтрока150 = Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(150));
	ВсеВызовыОписания = ВсеМодулиОбработчиков.СкопироватьКолонки();
	ВсеВызовыОписания.Колонки.Добавить("ИмяБиблиотеки", ТипСтрока150);
	ВсеВызовыОписания.Колонки.Добавить("ИмяПроцедуры", ТипСтрока150);
	
	ТекстыМодулейМенеджера = Новый Массив;
	Для Каждого Модуль Из ВсеМодулиОбработчиков Цикл
		
		РазметкаКода.ЭтоМодульМенеджера = СтрНайти(Модуль.ИмяОбъекта, "ОбщийМодуль") = 0;
		РазметкаКода.ДобавитьОбластьОписания = Ложь;
		
		Отбор = Новый Структура("МодульОбработчика", Модуль.МодульОбработчика);
		ОбработчикиОбъекта = ОбработчикиКОписанию.Скопировать(Отбор);
		ОбработчикиОбъекта.Сортировать("Процедура");
		БиблиотекиОбработчиков = ОбработчикиОбъекта.Скопировать(Отбор);
		БиблиотекиОбработчиков.Свернуть("ИмяБиблиотеки");
		БиблиотекиОбработчиков.Сортировать("ИмяБиблиотеки");
		ИменаБиблиотек = БиблиотекиОбработчиков.ВыгрузитьКолонку("ИмяБиблиотеки");
		
		Для Каждого Библиотека Из ИменаБиблиотек Цикл
			ИмяПроцедуры = "ПриДобавленииОбработчиковОбновления";
			Если ИменаБиблиотек.Количество() > 1 ИЛИ СтрНайти(Модуль.МодульОбработчика, "ОбновлениеИнформационнойБазы") > 0 Тогда
				ИмяПроцедуры = "ПриДобавленииОбработчиковОбновления" + Библиотека;
			КонецЕсли;
			Отбор = Новый Структура("ИмяБиблиотеки", Библиотека);
			Обработчики = ОбработчикиОбъекта.Скопировать(Отбор);
			Если ТолькоВыделенные И НЕ РасширенныйРежимФормы Тогда
				ОбработчикиКУдалению = Новый Массив;
				Для Каждого Обработчик Из Обработчики Цикл
					Если ВыделенныеОбработчики.Найти(Обработчик.Ссылка) = Неопределено Тогда
						ОбработчикиКУдалению.Добавить(Обработчик);
					КонецЕсли;
				КонецЦикла;
				Для Каждого КУдалению Из ОбработчикиКУдалению Цикл
					Обработчики.Удалить(КУдалению);
				КонецЦикла;
				Если Обработчики.Количество() = 0 Тогда
					Продолжить;
				КонецЕсли;
			КонецЕсли;
			
			РазметкаКода.ДобавитьОбластьОписания = Обработчики.Количество() > 1 ИЛИ НЕ РасширенныйРежимФормы;
			РазметкаКода.ИмяПроцедуры = ИмяПроцедуры;
			Если РазметкаКода.УстановитьТэги Тогда
				РазметкаКода.ИмяКонфигурации = ВсеИменаКонфигураций[Библиотека];
			КонецЕсли;
			
			НовыйВызов = ВсеВызовыОписания.Добавить();
			ЗаполнитьЗначенияСвойств(НовыйВызов, Модуль);
			НовыйВызов.ИмяБиблиотеки = Библиотека;
			НовыйВызов.ИмяПроцедуры = ИмяПроцедуры;
			
			Если ТолькоИзмененные И Модуль.Изменен ИЛИ НЕ ТолькоИзмененные Тогда
				ТекстОбработчиков = ТекстОбработчиков(Обработчики, РазметкаКода, Модуль.ВнешниеТэги);
				Если РасширенныйРежимФормы Тогда
					ПоместитьВПроцедуру(ИмяПроцедуры, ТекстОбработчиков, РазметкаКода);
				КонецЕсли;
				
				КодМодуля = ОписаниеКодаМодуля(Модуль.МодульОбработчика, ТекстОбработчиков, Обработчики[0].Процедура);
				КодМодуля.ЭтоПроцедураОписания = Истина;
				КодМодуля.ПутьМодуля = "CommonModules\" + Модуль.МодульОбработчика + "\Module.bsl";
				КодМодуля.ЗаголовокПроцедуры = "Процедура " + ИмяПроцедуры + "(Обработчики) Экспорт";
				КодМодуля.Вставить("ИменаБиблиотек", ИменаБиблиотек);
				Если СтрНайти(Модуль.МодульОбработчика, ".") > 0 Тогда
					Имена = СтрРазделить(Модуль.МодульОбработчика, ".");
					Имена[0] = АнглийскиеИмена[Имена[0]];
					КодМодуля.ПутьМодуля = СтрСоединить(Имена, "\") + "\ManagerModule.bsl";
					Если СтрНайти(КодМодуля.ПутьМодуля, "Constants") > 0 Тогда
						КодМодуля.ПутьМодуля = СтрЗаменить(КодМодуля.ПутьМодуля, "\ManagerModule.", "\ValueManagerModule.");
					КонецЕсли;
				КонецЕсли;
				ТекстыМодулейМенеджера.Добавить(КодМодуля);
			КонецЕсли;
			
		КонецЦикла;
		
	КонецЦикла;
	#КонецОбласти
	
	#Область СформироватьПроцедурыПриДобавленииОбработчиковОбновления
	Если НЕ ТолькоВыделенные И ОбновитьСписокВызовов Тогда
		ВсеВызовыОписания.Сортировать("ИмяБиблиотеки,МодульОбработчика");
		РазметкаКода.Вставить("ИмяПроцедуры", "ПриДобавленииОбработчиковОбновления");
		РазметкаКода.ЭтоПроцедураОписания = Ложь;
		РазметкаКода.ЭтоМодульМенеджера = Ложь;
		Для Каждого Библиотека Из ВсеИменаКонфигураций Цикл
			
			ИмяБиблиотеки = Библиотека.Ключ;
			ИмяКонфигурации = ВсеИменаКонфигураций[ИмяБиблиотеки];
			ОписаниеКонфигурации = ОписаниеКонфигураций[ИмяКонфигурации];
			ИмяОсновногоСерверногоМодуля = ОписаниеКонфигурации["module"];
			
			Если РазметкаКода.УстановитьТэги Тогда
				РазметкаКода.Вставить("ИмяКонфигурации", ИмяКонфигурации);
				РазметкаКода.Вставить("ИмяМодуля", ИмяОсновногоСерверногоМодуля);
				РазметкаКода.Вставить("МодульЛокализации", ОписаниеКонфигурации["localization"] <> Неопределено);
				Если РазметкаКода.МодульЛокализации Тогда
					Если ОписаниеКонфигурации["outTags"].Количество() > 0 Тогда
						РазметкаКода.Вставить("ТэгиЛокализации", ОписаниеКонфигурации["outTags"][0]);
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
			
			Отбор = Новый Структура("ИмяБиблиотеки", ИмяБиблиотеки);
			МодулиОбработчиков = ВсеВызовыОписания.Скопировать(Отбор);
			
			КодМодуля = ОписаниеКодаМодуля(ИмяОсновногоСерверногоМодуля);
			КодМодуля.ТекстПроцедуры = ТекстПриДобавленииОбработчиковОбновления(МодулиОбработчиков, РазметкаКода);
			КодМодуля.ПутьМодуля = "CommonModules\" + ИмяОсновногоСерверногоМодуля + "\Module.bsl";
			КодМодуля.ЗаголовокПроцедуры = "Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт";
			ТекстыМодулей.Добавить(КодМодуля);
			
		КонецЦикла;
	КонецЕсли;
	Для Каждого ТекстМодуляМенеджера Из ТекстыМодулейМенеджера Цикл
		ТекстыМодулей.Добавить(ТекстМодуляМенеджера);
	КонецЦикла;
	#КонецОбласти
	
	Если ВерсияКонфигурации <> НоваяВерсияКонфигурации Тогда
		УстановитьВерсиюМодуля(ТекстыМодулей, ВерсииМодулей);
	КонецЕсли;
	
	Если НЕ РежимОтладкиОписанияОбработчиков Тогда
		СброситьФлагИзменен();
	КонецЕсли;
	
	Если ТолькоВыделенные И НЕ РасширенныйРежимФормы Тогда
		КодОбработчиков = ОписаниеКодаМодуля(НСтр("ru = 'Выделенные обработчики'"));
		Для Каждого КодМодуля Из ТекстыМодулей Цикл
			КодОбработчиков.ТекстПроцедуры = КодОбработчиков.ТекстПроцедуры + КодМодуля.ТекстПроцедуры + Символы.ПС + Символы.ПС;
		КонецЦикла;
		ТекстыМодулей = Новый Массив;
		ТекстыМодулей.Добавить(КодОбработчиков);
	КонецЕсли;
	
	Возврат ТекстыМодулей;
	
КонецФункции

&НаСервере
Процедура ЗаполнитьОписание(ОписаниеКонфигураций, ИменаКонфигураций)
	
	ПодсистемыКонфигурации = СтандартныеПодсистемыПовтИсп.ОписанияПодсистем();
	Для Каждого Подсистема Из ПодсистемыКонфигурации.ПоИменам Цикл
		ИмяМодуля = Подсистема.Значение.ОсновнойСерверныйМодуль;
		КраткоеИмяБиблиотеки = СтрЗаменить(ИмяМодуля, "ОбновлениеИнформационнойБазы", "");
		ИменаКонфигураций.Добавить(КраткоеИмяБиблиотеки);
		Описание = Новый Структура("module", Подсистема.Значение.ОсновнойСерверныйМодуль);
		Описание.Вставить("name", Подсистема.Значение.Имя);
		ОписаниеКонфигураций.Вставить(КраткоеИмяБиблиотеки, Описание);
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Процедура ДобавитьВерсиюМодуля(ВерсииМодулей, ОбработчикиМодуля)
	
	Если ОбработчикиМодуля.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Обработка = ОбъектОбработки();
	ОбработчикиМодуля.Сортировать("РедакцияЧислом УБЫВ");
	
	Максимум = ОбработчикиМодуля[0];
	ЭтоРазрабатываемаяБиблиотека = РазрабатываемыеПодсистемы.Найти(Максимум.Подсистема) <> Неопределено;
	
	Если ЭтоРазрабатываемаяБиблиотека Тогда
		Описание = ВерсииМодулей.Добавить();
		Описание.ИмяМодуля = Максимум.ИмяОсновногоСерверногоМодуля;
		Описание.Версия = Максимум.Версия;
	КонецЕсли;
	
	// Проверим максимальный номер сборки из обработчиков модуля
	Если ЗначениеЗаполнено(Максимум.Версия) Тогда
		НомераМаксимум = СтрРазделить(Максимум.Версия, ".");
	Иначе
		НомераМаксимум = СтрРазделить(НоваяВерсияКонфигурации, ".");
	КонецЕсли;
	ПерваяЦифраМаксимум = НомераМаксимум[0];
	НомераМаксимум.Удалить(0);
	Максимум3Последних = Обработка.ВерсияЧислом(НомераМаксимум);
	
	НомераКонфигурации = СтрРазделить(НоваяВерсияКонфигурации, ".");
	ПерваяЦифраКонфигурации = НомераКонфигурации[0];
	НомераКонфигурации.Удалить(0);
	Конфигурация3Последних = Обработка.ВерсияЧислом(НомераКонфигурации);
	Если ЭтоРазрабатываемаяБиблиотека
		И Число(ПерваяЦифраМаксимум) >= Число(ПерваяЦифраКонфигурации) 
		И Максимум3Последних > Конфигурация3Последних Тогда
		НоваяВерсияКонфигурации = ПерваяЦифраКонфигурации + "." + СтрСоединить(НомераМаксимум, ".");
	КонецЕсли;
	
	// Проверим номер сборки заданный пользователем
	НомераКонфигурации = СтрРазделить(НоваяВерсияКонфигурации, ".");
	Если ЭтоРазрабатываемаяБиблиотека
		И НовыйНомерСборкиКонфигурации > Число(НомераКонфигурации[3]) Тогда
		НомераКонфигурации[3] = Формат(НовыйНомерСборкиКонфигурации, "ЧН=0; ЧГ=0");
		НоваяВерсияКонфигурации = СтрСоединить(НомераКонфигурации, ".");
		НомераМаксимум[3] = НомераКонфигурации[3];
	КонецЕсли;
	
	НомераМаксимум.Вставить(0,0);
	
	Если ЭтоРазрабатываемаяБиблиотека Тогда
		Описание.ВерсияРедакции = СтрСоединить(НомераМаксимум, ".");
		Описание.РедакцияЧислом = Обработка.ВерсияЧислом(Описание.ВерсияРедакции);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура УстановитьВерсиюМодуля(ТекстыМодулей, Модули)
	
	Если Модули.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Модули.Сортировать("РедакцияЧислом УБЫВ");
	Максимум = Модули[0];
	Для Каждого Описание Из ТекстыМодулей Цикл
		
		Модуль = Модули.Найти(Описание.ИмяМодуля, "ИмяМодуля");
		Если Модуль = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		НомераВерсии = СтрРазделить(Модуль.Версия, ".");
		НовыеНомера = СтрРазделить(Максимум.ВерсияРедакции, ".");
		НовыеНомера[0] = НомераВерсии[0];
		Описание.Версия = СтрСоединить(НовыеНомера, ".");
		
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Функция ОписаниеКодаМодуля(ИмяМодуля = "", ТекстПроцедуры = "", ПроцедураОбработки = "")
	
	Описание = Новый Структура;
	Описание.Вставить("ИмяМодуля", ИмяМодуля);
	Описание.Вставить("ЗаголовокПроцедуры", "");
	Описание.Вставить("ТекстПроцедуры", ТекстПроцедуры);
	Описание.Вставить("ПроцедураОбработки", ПроцедураОбработки);
	Описание.Вставить("ПутьМодуля", "");
	Описание.Вставить("Версия", "");
	Описание.Вставить("ЭтоПроцедураОписания", Ложь);
	Описание.Вставить("ПроцедураВерсии", "Процедура ПриДобавленииПодсистемы(Описание) Экспорт");
	Возврат Описание;
	
КонецФункции

&НаСервере
Функция ОписаниеВерсийМодулей()
	
	Описание = Новый ТаблицаЗначений;
	Описание.Колонки.Добавить("ИмяМодуля", Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(150)));
	Описание.Колонки.Добавить("Версия", , Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(30)));
	Описание.Колонки.Добавить("ВерсияРедакции", , Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(30)));
	Описание.Колонки.Добавить("РедакцияЧислом", Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(10, 0)));
	Возврат Описание;
	
КонецФункции

&НаСервере
Функция МодулиОбработчиковОбновления(Обработчики, РазметкаКода, ВыделенныеОбработчики = Неопределено)
	
	ТипСтрока150 = Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(150));
	Обработчики.Колонки.Добавить("МодульОбработчика", ТипСтрока150);
	Обработчики.Колонки.Добавить("ТэгиМодуляОбновления", ТипСтрока150);
	Обработчики.Колонки.Добавить("ВнешниеТэги", ТипСтрока150);
	
	ТэгиМодуля = "";
	Если РазметкаКода.УстановитьТэги Тогда
		ОписаниеТэгов = РазметкаКода.Тэги.ПоОбъектам.Найти("ОбщийМодуль."+РазметкаКода.ИмяМодуля, "Имя");
		Если ОписаниеТэгов <> Неопределено Тогда
			ТэгиМодуля = ОписаниеТэгов.Тэги;
		КонецЕсли;
	КонецЕсли;
	ВыводитьТолькоВыделенные = ВыделенныеОбработчики <> Неопределено И ВыделенныеОбработчики.Количество() > 0;
	ВыделенныеОбработчикиМодуля = Новый Массив;
	Для Каждого Обработчик Из Обработчики Цикл
		
		ЧастиИмени = СтрРазделить(Обработчик.Процедура, ".");
		ЧастиИмени.Удалить(ЧастиИмени.ВГраница());
		Обработчик.МодульОбработчика = СтрСоединить(ЧастиИмени, ".");
		Обработчик.ИмяОбъекта = Обработчик.МодульОбработчика;
		Если ЧастиИмени.Количество() = 1 Тогда
			ЧастиИмени.Вставить(0, "ОбщийМодуль");
		Иначе
			ЧастиИмени[0] = ЕдинственноеЧисло[ЧастиИмени[0]];
		КонецЕсли;
		Обработчик.ИмяОбъекта = СтрСоединить(ЧастиИмени, ".");
		Обработчик.ТэгиМодуляОбновления = ТэгиМодуля;
		Если РазметкаКода.УстановитьТэги И РазметкаКода.МодульЛокализации Тогда
			Обработчик.ТэгиМодуляОбновления = РазметкаКода.ТэгиЛокализации;
		КонецЕсли;
		
		Если ВыводитьТолькоВыделенные Тогда
			ОбработчикВыделен = ВыделенныеОбработчики.Найти(Обработчик.Ссылка) <> Неопределено;
		КонецЕсли;
			
		Если ВыводитьТолькоВыделенные И ОбработчикВыделен Тогда
			ВыделенныеОбработчикиМодуля.Добавить(Обработчик.ИмяОбъекта);
		КонецЕсли;
		
	КонецЦикла;
	МодулиОбработчиков = Обработчики.Скопировать();
	МодулиОбработчиков.Свернуть("МодульОбработчика,ИмяОбъекта,ВнешниеТэги", "Изменен");
	МодулиОбработчиков.Сортировать("МодульОбработчика");
	
	Если ВыводитьТолькоВыделенные Тогда
		Выделенные = МодулиОбработчиков.СкопироватьКолонки();
		Для Каждого Выделенный Из ВыделенныеОбработчикиМодуля Цикл
			НайденныеСтроки = МодулиОбработчиков.НайтиСтроки(Новый Структура("ИмяОбъекта", Выделенный));
			Для Каждого Найденный Из НайденныеСтроки Цикл
				ЗаполнитьЗначенияСвойств(Выделенные.Добавить(), Найденный);
			КонецЦикла;
		КонецЦикла;
		Возврат Выделенные;
	КонецЕсли;
	
	Возврат МодулиОбработчиков;
	
КонецФункции

&НаСервере
Функция ВыделенныеОбработчики()
	
	Результат = Новый Массив;
	Для Каждого ИдСтроки Из Элементы.ОбработчикиОбновления.ВыделенныеСтроки Цикл
		Обработчик = Объект.ОбработчикиОбновления.НайтиПоИдентификатору(ИдСтроки);
		Результат.Добавить(Обработчик.Ссылка);
	КонецЦикла;
	Возврат Результат;
	
КонецФункции

&НаСервере
Процедура СброситьФлагИзменен()
	
	Отбор = Новый Структура("Изменен", Истина);
	Найденные = Объект.ОбработчикиОбновления.НайтиСтроки(Отбор);
	Для Каждого Обработчик Из Найденные Цикл
		Обработчик.Изменен = Ложь;
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область ФормированиеКодаПроцедур

&НаСервере
Функция ТекстОбработчиков(Обработчики, РазметкаКода, ВнешниеТэги = Неопределено)
	
	ТипСтрока100 = Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(0));
	Обработчики.Колонки.Добавить("Тэги", ТипСтрока100);
	Если РазметкаКода.УстановитьТэги Тогда
		Если РазметкаКода.МодульЛокализации И ВнешниеТэги = Неопределено Тогда
			ЗаполнитьТэгиОбъектов("ИмяОбъекта", Обработчики, РазметкаКода, РазметкаКода.ТэгиЛокализации, Ложь);
		КонецЕсли;
		Если ВнешниеТэги <> Неопределено Тогда
			Для Каждого Обработчик Из Обработчики Цикл
				Если СтрНайти(ВнешниеТэги, Обработчик.ТэгиМодуляОбновления) = 0 Тогда
					Обработчик.Тэги = Обработчик.Тэги + ?(ПустаяСтрока(Обработчик.Тэги),"",",") + Обработчик.ТэгиМодуляОбновления;
				КонецЕсли;
				Обработчик.ТэгиМодуляОбновления = ВнешниеТэги;
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;
	
	ДеревоТэгов = СвернутьПоТегам(Обработчики, РазметкаКода);
	СтрокиГруппОбработчиков = Новый Массив;
	Для Каждого Ветка Из ДеревоТэгов.Строки Цикл
		ТекстГруппыОбработчиков = ТекстГруппыОбработчиковРекурсивно(Ветка, РазметкаКода, СтрокиГруппОбработчиков.Количество() = 0);
		СтрокиГруппОбработчиков.Добавить(ТекстГруппыОбработчиков);
	КонецЦикла;
	ТекстОбработчиков = СтрСоединить(СтрокиГруппОбработчиков, Символы.ПС);
	
	Возврат ТекстОбработчиков;
	
КонецФункции

// Параметры:
//   Ветка - СтрокаДереваЗначений
//   РазметкаКода - Структура:
//   * Тэги - см. ПолучитьСведенияОТегахВырезки
//   * ДобавитьОбластьОписания - Булево
//   * ЭтоМодульМенеджера - Булево
//   * ТэгиЛокализации - Строка
//   * ИмяПроцедуры - Строка
//   ПервыйВГруппе - Булево
// Возвращаемое значение:
//   Строка
//
&НаСервере
Функция ТекстГруппыОбработчиковРекурсивно(Ветка, РазметкаКода, ПервыйВГруппе = Истина)
	
	СтрокиОбработчиков = Новый Массив;
	Для Каждого Обработчик Из Ветка.Строки Цикл
		Если Обработчик.Строки.Количество() > 0 Тогда
			ТекстГруппыОбработчиков = ТекстГруппыОбработчиковРекурсивно(Обработчик, РазметкаКода, СтрокиОбработчиков.Количество() = 0);
			СтрокиОбработчиков.Добавить(ТекстГруппыОбработчиков);
			Продолжить;
		КонецЕсли;
		ВнешниеТэги = "";
		Если РазметкаКода.УстановитьТэги Тогда
			ВнешниеТэги = Обработчик.Тэги + ?(ПустаяСтрока(Обработчик.Тэги),"",",") + Обработчик.ТэгиМодуляОбновления;
			РазметкаКода.ИмяМодуля = Обработчик.ИмяОсновногоСерверногоМодуля;
		КонецЕсли;
		ТекстОбработчика = ТекстОписанияОбработчика(Обработчик, РазметкаКода, ВнешниеТэги);
		Если СтрокиОбработчиков.Количество() > 0 Тогда
			ТекстОбработчика = Символы.ПС + ТекстОбработчика;
		КонецЕсли;
		СтрокиОбработчиков.Добавить(ТекстОбработчика);
	КонецЦикла;
	
	ТекстОбработчиков = СтрСоединить(СтрокиОбработчиков, Символы.ПС);
	Если РазметкаКода.УстановитьТэги 
		И НЕ ПустаяСтрока(Ветка.Тэги) И НЕ РазметкаКода.ЭтоПроцедураОписания Тогда
		Шаблон = "%1" + Символы.ПС + "%2" + Символы.ПС + "%3";
		Если НЕ ПервыйВГруппе Тогда
			Шаблон = "%1" + Символы.ПС + Символы.ПС + "%2" + Символы.ПС + "%3";
		КонецЕсли;
		Для Каждого Тэг Из СтрРазделить(Ветка.Тэги, ",") Цикл
			ОписаниеТэга = РазметкаКода.Тэги.Описание[Тэг]; // см. ОписаниеТэга
			ТекстОбработчиков = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ОписаниеТэга.Начало, ТекстОбработчиков, ОписаниеТэга.Конец);
		КонецЦикла;
		
	ИначеЕсли НЕ ПервыйВГруппе Тогда
		ТекстОбработчиков = Символы.ПС + ТекстОбработчиков;
		
	КонецЕсли;
	
	Возврат ТекстОбработчиков;
	
КонецФункции

&НаСервере
Функция ТекстПриДобавленииОбработчиковОбновления(МодулиОбработчиков, РазметкаКода)
	
	МодулиОбработчиков.Колонки.Добавить("Тэги", Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(100)));
	Если РазметкаКода.УстановитьТэги Тогда
		Если РазметкаКода.МодульЛокализации Тогда
			ЗаполнитьТэгиОбъектов("ИмяОбъекта", МодулиОбработчиков, РазметкаКода, РазметкаКода.ТэгиЛокализации, Ложь);
		ИначеЕсли РазметкаКода.Свойство("ТэгиЛокализации") И НЕ ПустаяСтрока(РазметкаКода.ТэгиЛокализации) Тогда
			Для Каждого Модуль Из МодулиОбработчиков Цикл
				Если СтрНайти(Модуль.ВнешниеТэги, РазметкаКода.ТэгиЛокализации) > 0 Тогда
					Модуль.Тэги = РазметкаКода.ТэгиЛокализации;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
	КонецЕсли;
	
	ДеревоТэгов = СвернутьПоТегам(МодулиОбработчиков, РазметкаКода);
	СтрокиГруппВызовов = Новый Массив;
	Для Каждого Ветка Из ДеревоТэгов.Строки Цикл
		ТекстГруппыВызовов = ТекстГруппыВызововРекурсивно(Ветка, РазметкаКода);
		СтрокиГруппВызовов.Добавить(ТекстГруппыВызовов);
	КонецЦикла;
	ТекстПроцедуры = СтрСоединить(СтрокиГруппВызовов, Символы.ПС);
	
	ПоместитьВПроцедуру("ПриДобавленииОбработчиковОбновления", ТекстПроцедуры, РазметкаКода);
	
	Возврат ТекстПроцедуры;
	
КонецФункции

// Параметры:
//   Ветка - СтрокаДереваЗначений
//   РазметкаКода - Структура:
//   * Тэги - см. ПолучитьСведенияОТегахВырезки
//   * ДобавитьОбластьОписания - Булево
//   * ЭтоМодульМенеджера - Булево
//   * ТэгиЛокализации - Строка
//   * ИмяПроцедуры - Строка
// Возвращаемое значение:
//   Строка
//
&НаСервере
Функция ТекстГруппыВызововРекурсивно(Ветка, РазметкаКода)
	
	СтрокиВызовов = Новый Массив;
	Для Каждого МодульОбработчика Из Ветка.Строки Цикл
		Если МодульОбработчика.Строки.Количество() > 0 Тогда
			ТекстГруппыОбработчиков = ТекстГруппыВызововРекурсивно(МодульОбработчика, РазметкаКода);
			СтрокиВызовов.Добавить(ТекстГруппыОбработчиков);
			Продолжить;
		КонецЕсли;
		
		ИмяПроцедуры = МодульОбработчика.ИмяПроцедуры + "(Обработчики)";
		ТекстВызова = Символы.Таб + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку("%1.%2;", МодульОбработчика.МодульОбработчика, ИмяПроцедуры);
		СтрокиВызовов.Добавить(ТекстВызова);
	КонецЦикла;
	
	ТекстОбработчиков = СтрСоединить(СтрокиВызовов, Символы.ПС);
	Если НЕ ПустаяСтрока(Ветка.Тэги) Тогда
		Шаблон = "%1" + Символы.ПС + "%2" + Символы.ПС + "%3";
		Для Каждого Тэг Из СтрРазделить(МодульОбработчика.Тэги, ",") Цикл
			ОписаниеТэга = РазметкаКода.Тэги.Описание[Тэг]; // см. ОписаниеТэга
			ТекстОбработчиков = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ОписаниеТэга.Начало, ТекстОбработчиков, ОписаниеТэга.Конец);
		КонецЦикла;
	КонецЕсли;
	
	Возврат ТекстОбработчиков;
	
КонецФункции

// Параметры:
//   Обработчик - СтрокаДереваЗначений:
//    * Идентификатор - УникальныйИдентификатор
//   РазметкаКода - Структура:
//   * Тэги - см. ПолучитьСведенияОТегахВырезки
//   * ИмяПроцедуры - Строка
//   * ДобавитьОбластьОписания - Булево
//   * ЭтоМодульМенеджера - Булево
//   * ТэгиЛокализации - Строка
//   ТэгиОбработчика - Строка
// Возвращаемое значение:
//   Строка
//
&НаСервере
Функция ТекстОписанияОбработчика(Обработчик, РазметкаКода, ТэгиОбработчика)
	
	СтрокиОбработчика = Новый Массив;
	СтрокиОбработчика.Добавить("	Обработчик = Обработчики.Добавить();");
	СтрокиОбработчика.Добавить("Обработчик.Процедура = """ + Обработчик.Процедура + """;");
	СтрокиОбработчика.Добавить("Обработчик.Версия = """ + Обработчик.Версия + """;");
	СтрокиОбработчика.Добавить("Обработчик.РежимВыполнения = """ + Строка(Обработчик.РежимВыполнения) + """;");
	
	Если Обработчик.НачальноеЗаполнение Тогда
		СтрокиОбработчика.Добавить("Обработчик.НачальноеЗаполнение = Истина;");
	КонецЕсли;
	
	Если НЕ ПустаяСтрока(Обработчик.Идентификатор) Тогда
		ИД = Новый УникальныйИдентификатор(Обработчик.Идентификатор);
		Если ЗначениеЗаполнено(ИД) Тогда
			СтрокиОбработчика.Добавить("Обработчик.Идентификатор = Новый УникальныйИдентификатор(""" + Обработчик.Идентификатор + """);");
		КонецЕсли;
	КонецЕсли;
	
	Если Обработчик.ОбщиеДанные Тогда
		СтрокиОбработчика.Добавить("Обработчик.ОбщиеДанные = Истина;");
	КонецЕсли;
	
	Если Обработчик.УправлениеОбработчиками Тогда
		СтрокиОбработчика.Добавить("Обработчик.УправлениеОбработчиками = Истина;");
	КонецЕсли;
	
	Если Обработчик.Многопоточный Тогда
		СтрокиОбработчика.Добавить("Обработчик.Многопоточный = Истина;");
	КонецЕсли;
	
	ОтложенныйРежимВыполнения = Обработчик.РежимВыполнения = "Отложенно";
	Если ОтложенныйРежимВыполнения Тогда
		СтрокиОбработчика.Добавить("Обработчик.ПроцедураЗаполненияДанныхОбновления = """ + Обработчик.ПроцедураЗаполненияДанныхОбновления + """;");
		СтрокиОбработчика.Добавить("Обработчик.ПроцедураПроверки = """ + Обработчик.ПроцедураПроверки + """;");
	КонецЕсли;
	
	Если Обработчик.ЗапускатьТолькоВГлавномУзле Тогда
		СтрокиОбработчика.Добавить("Обработчик.ЗапускатьТолькоВГлавномУзле = Истина;");
	КонецЕсли;
	
	Если Обработчик.ЗапускатьИВПодчиненномУзлеРИБСФильтрами Тогда
		СтрокиОбработчика.Добавить("Обработчик.ЗапускатьИВПодчиненномУзлеРИБСФильтрами = Истина;");
	КонецЕсли;
	
	Если Обработчик.Порядок <> Перечисления.ПорядокОбработчиковОбновления.Обычный Тогда
		СтрокиОбработчика.Добавить("Обработчик.Порядок = Перечисления.ПорядокОбработчиковОбновления."+Строка(Обработчик.Порядок)+";");
	КонецЕсли;
	
	Если ПустаяСтрока(Обработчик.Комментарий)Тогда
		СтрокиОбработчика.Добавить("Обработчик.Комментарий = """";");
	Иначе
		ТекстКомментария = СокрЛП(Обработчик.Комментарий);
		ТекстКомментария = СтрЗаменить(ТекстКомментария, Символы.ПС, Символы.ПС + "	|");
		ТекстКомментария = СтрЗаменить(ТекстКомментария, """", """""");
		СтрокиОбработчика.Добавить("Обработчик.Комментарий = НСтр(""ru = '" + ТекстКомментария +"'"");");
	КонецЕсли;
	
	ТекстЧитаемыеОбъекты = ТекстИнформацииОбОбъектах(Обработчик, "ЧитаемыеОбъекты", РазметкаКода, ТэгиОбработчика);
	Если НЕ ПустаяСтрока(ТекстЧитаемыеОбъекты) Тогда
		СтрокиОбработчика.Добавить(ТекстЧитаемыеОбъекты);
	КонецЕсли;
	
	ТекстИзменяемыеОбъекты = ТекстИнформацииОбОбъектах(Обработчик, "ИзменяемыеОбъекты", РазметкаКода, ТэгиОбработчика);
	Если НЕ ПустаяСтрока(ТекстИзменяемыеОбъекты) Тогда
		СтрокиОбработчика.Добавить(ТекстИзменяемыеОбъекты);
	КонецЕсли;
	
	ТекстНовыеОбъекты = ТекстИнформацииОбОбъектах(Обработчик, "НовыеОбъекты", РазметкаКода, ТэгиОбработчика);
	Если НЕ ПустаяСтрока(ТекстНовыеОбъекты) Тогда
		СтрокиОбработчика.Добавить(ТекстНовыеОбъекты);
	КонецЕсли;
	
	Если ОтложенныйРежимВыполнения Тогда
		ТекстБлокируемыеОбъекты = ТекстИнформацииОбОбъектах(Обработчик, "БлокируемыеОбъекты", РазметкаКода, ТэгиОбработчика);
		Если НЕ ПустаяСтрока(ТекстБлокируемыеОбъекты) Тогда
			СтрокиОбработчика.Добавить(ТекстБлокируемыеОбъекты);
		КонецЕсли;
	КонецЕсли;
	
	Если ОтложенныйРежимВыполнения Тогда
		ТекстПриоритетыВыполнения = ТекстПриоритетовВыполнения(Обработчик, РазметкаКода, ТэгиОбработчика);
		Если НЕ ПустаяСтрока(ТекстПриоритетыВыполнения) Тогда
			СтрокиОбработчика.Добавить(ТекстПриоритетыВыполнения);
		КонецЕсли;
	КонецЕсли;
	ТекстОбработчика = СтрСоединить(СтрокиОбработчика, Символы.ПС + Символы.Таб);
	
	ШаблонОбласти = 
	"#Область %1
	|
	|%2
	|
	|#КонецОбласти";
	ИмяОбласти = СтрЗаменить(Обработчик.Процедура, ".", "_");
	Если РазметкаКода.ЭтоПроцедураОписания И РасширенныйРежимФормы Тогда
		Имена = СтрРазделить(Обработчик.Процедура, ".");
		ИмяОбласти = Имена[Имена.ВГраница()];
	КонецЕсли;
	Результат = ТекстОбработчика;
	Если РазметкаКода.ДобавитьОбластьОписания Тогда
		Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонОбласти, ИмяОбласти, ТекстОбработчика);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

// Параметры:
//   Обработчик - СтрокаДереваЗначений:
//   * Ссылка - Строка
//   * Идентификатор - УникальныйИдентификатор
//   РазметкаКода - Структура:
//   * ДобавитьОбластьОписания - Булево
//   * ЭтоМодульМенеджера - Булево
//   * ТэгиЛокализации - Строка
//   * ИмяПроцедуры - Строка
//   ТэгиОбработчика - Строка
// Возвращаемое значение:
//   Строка
//
&НаСервере
Функция ТекстПриоритетовВыполнения(Обработчик, РазметкаКода, ТэгиОбработчика)
	
	Отбор = Новый Структура("Ссылка", Обработчик.Ссылка);
	ПриоритетыВыполнения = Объект.ПриоритетыВыполнения.Выгрузить(Отбор);
	Отбор = Новый Структура("ОбработчикЧитательИлиПисатель2", Обработчик.Ссылка);
	Конфликты = Объект.КонфликтыОбработчиков.Выгрузить(Отбор);
	ПриоритетыКонфликтовЧитаемыхИлиДвойнойЗаписи(ПриоритетыВыполнения, Конфликты);
	
	ТекстПриоритетов = "";
	Если ПриоритетыВыполнения.Количество() = 0 Тогда
		Возврат ТекстПриоритетов;
	КонецЕсли;
		
	ТекстПриоритетов = ТекстПриоритетов + "
	|	Обработчик.ПриоритетыВыполнения = ОбновлениеИнформационнойБазы.ПриоритетыВыполненияОбработчика();
	|
	|";
	
	ПриоритетыВыполнения.Колонки.Добавить("Тэги", Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(100)));
	Если РазметкаКода.УстановитьТэги Тогда
		ЗаполнитьТэгиОбъектов("Процедура2", ПриоритетыВыполнения, РазметкаКода, ТэгиОбработчика);
	КонецЕсли;
	тз = ПриоритетыВыполнения.Скопировать(,"Тэги");
	тз.Свернуть("Тэги");
	тз.Сортировать("Тэги");
	ТэгиВсехОбъектов = тз.ВыгрузитьКолонку("Тэги");
	
	ОписанияВсехТэгов = Новый Соответствие;
	ШаблонПриоритета = 
	"	НоваяСтрока = Обработчик.ПриоритетыВыполнения.Добавить();
	|	НоваяСтрока.Процедура = ""%1"";
	|	НоваяСтрока.Порядок = ""%2"";";
	ТекстыТэгов = Новый Массив;
	Для ИндексОбщий = 0 По ТэгиВсехОбъектов.ВГраница() Цикл
		Тэги = ТэгиВсехОбъектов[ИндексОбщий];
		Отбор = Новый Структура("Тэги", Тэги);
		ПриоритетыТэга = ПриоритетыВыполнения.НайтиСтроки(Отбор);
		СтрокиТэга = Новый Массив;
		Для Каждого Приоритет Из ПриоритетыТэга Цикл
			СтрокаПриоритета = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонПриоритета,Приоритет.Процедура2,Приоритет.Порядок);
			СтрокиТэга.Добавить(СтрокаПриоритета);
		КонецЦикла;
		
		ТекстТэга = СтрСоединить(СтрокиТэга, Символы.ПС + Символы.ПС);
		Если НЕ ПустаяСтрока(Тэги) Тогда
			МассивТэгов = СтрРазделить(Тэги, ",");
			Для Индекс = 0 По МассивТэгов.ВГраница() Цикл
				Тэг = МассивТэгов[Индекс];
				Шаблон = "	%1" + Символы.ПС + "%2" + Символы.ПС + "	%3";
				Если (Индекс + 1)%2 <> 0 И МассивТэгов.Количество() > 1 Тогда
					Шаблон = Символы.ПС + "	%1" + Символы.ПС + "%2" + Символы.ПС + "	%3" + Символы.ПС;
				КонецЕсли;
				ОписаниеТэга = РазметкаКода.Тэги.Описание[Тэг]; // см. ОписаниеТэга
				ТекстТэга = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ОписаниеТэга.Начало, ТекстТэга, ОписаниеТэга.Конец);
				ОписанияВсехТэгов.Вставить(Тэг, ОписаниеТэга);
			КонецЦикла;
			ТекстТэга = СтрЗаменить(ТекстТэга, "		", "	");
		КонецЕсли;
		Если ЗначениеЗаполнено(Тэги) И ИндексОбщий <> ТэгиВсехОбъектов.ВГраница() Тогда
			ТекстТэга = ТекстТэга + Символы.ПС;
		КонецЕсли;
		ТекстыТэгов.Добавить(ТекстТэга);
	КонецЦикла;
	ТекстТэгов = СтрСоединить(ТекстыТэгов, Символы.ПС);
	
	Шаблон = "	%1
			|	%2
			|";
	Для Каждого ОписаниеТэга Из ОписанияВсехТэгов Цикл
		КонецНачало = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ОписаниеТэга.Значение.Конец, ОписаниеТэга.Значение.Начало);
		ТекстТэгов = СтрЗаменить(ТекстТэгов, КонецНачало, "");
	КонецЦикла;
	ТекстПриоритетов = ТекстПриоритетов + ТекстТэгов; 
	
	Возврат ТекстПриоритетов;
	
КонецФункции

// Параметры:
//   Обработчик - СтрокаДереваЗначений:
//   * Ссылка - Строка
//   * Идентификатор - УникальныйИдентификатор
//   ИмяНабораОбъектов - Строка
//   РазметкаКода - Структура:
//   * ДобавитьОбластьОписания - Булево
//   * ЭтоМодульМенеджера - Булево
//   * ТэгиЛокализации - Строка
//   * ИмяПроцедуры - Строка
//   ТэгиОбработчика - Строка
// Возвращаемое значение:
//   Строка
//
&НаСервере
Функция ТекстИнформацииОбОбъектах(Обработчик, ИмяНабораОбъектов, РазметкаКода, ТэгиОбработчика)
	
	Отбор = Новый Структура("Ссылка", Обработчик.Ссылка);
	Если ИмяНабораОбъектов = "НовыеОбъекты" Тогда
		Отбор.Вставить("НовыеОбъекты", Истина);
		ОбъектыОбработчика = Объект["ИзменяемыеОбъекты"].Выгрузить(Отбор);
	Иначе
		ОбъектыОбработчика = Объект[ИмяНабораОбъектов].Выгрузить(Отбор);
	КонецЕсли;
	Если ИмяНабораОбъектов = "БлокируемыеОбъекты" Тогда
		Отбор.Вставить("БлокироватьИнтерфейс", Истина);
		БлокируемыеОбъекты = Объект["ИзменяемыеОбъекты"].Выгрузить(Отбор);
		ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(БлокируемыеОбъекты, ОбъектыОбработчика);
		БлокируемыеОбъекты = Объект["ЧитаемыеОбъекты"].Выгрузить(Отбор);
		ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(БлокируемыеОбъекты, ОбъектыОбработчика);
		ОбъектыОбработчика.Свернуть("ОбъектМетаданных");
		ОбъектыОбработчика.Сортировать("ОбъектМетаданных");
	КонецЕсли;
	Если ОбъектыОбработчика.Количество() = 0 Тогда
		Возврат "";
	КонецЕсли;
	Если РазметкаКода.УстановитьТэги Тогда
		ЗаполнитьТэгиОбъектов("ОбъектМетаданных", ОбъектыОбработчика, РазметкаКода, ТэгиОбработчика);
	КонецЕсли;
	
	ИмяНабора = СтрЗаменить(ИмяНабораОбъектов, "Объекты", "");
	ДеревоТэгов = СвернутьПоТегам(ОбъектыОбработчика, РазметкаКода);
	СтрокиГруппОбъектов = Новый Массив;
	Для Индекс = 0 По ДеревоТэгов.Строки.Количество()-1 Цикл
		Ветка = ДеревоТэгов.Строки[Индекс];
		ТекстГруппыОбъектов = ТекстГруппыОбъектовРекурсивно(Ветка, РазметкаКода, ИмяНабора);
		Если ЗначениеЗаполнено(Ветка.Тэги) И Индекс <> ДеревоТэгов.Строки.Количество()-1 Тогда
			ТекстГруппыОбъектов = ТекстГруппыОбъектов + Символы.ПС;
		КонецЕсли;
		СтрокиГруппОбъектов.Добавить(ТекстГруппыОбъектов);
	КонецЦикла;
	ТекстОбъектов = СтрСоединить(СтрокиГруппОбъектов, Символы.ПС);
	Шаблон = "
	|	%1 = Новый Массив;
	|%2
	|	Обработчик.%3 = СтрСоединить(%1, "","");";
	Результат = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ИмяНабора, ТекстОбъектов, ИмяНабораОбъектов);
	
	Возврат Результат;
	
КонецФункции

&НаСервере
Функция ТекстГруппыОбъектовРекурсивно(Ветка, РазметкаКода, ИмяНабораОбъектов)
	
	СтрокиОбъектов = Новый Массив;
	Для Каждого ОбъектМетаданных Из Ветка.Строки Цикл
		Если ОбъектМетаданных.Строки.Количество() > 0 Тогда
			ТекстГруппыОбъектов = ТекстГруппыОбъектовРекурсивно(ОбъектМетаданных, РазметкаКода, ИмяНабораОбъектов);
			СтрокиОбъектов.Добавить(ТекстГруппыОбъектов);
			Продолжить;
		КонецЕсли;
		ТекстОбъекта = Символы.Таб + ИмяНабораОбъектов + ".Добавить(" + ПолныйПутьМетаданныхОбъекта(ОбъектМетаданных.ОбъектМетаданных) + ");";
		СтрокиОбъектов.Добавить(ТекстОбъекта);
	КонецЦикла;
	
	ТекстОбъектов = СтрСоединить(СтрокиОбъектов, Символы.ПС);
	Если СтрНачинаетсяС(СокрЛП(СтрокиОбъектов[СтрокиОбъектов.ВГраница()]), "//") Тогда
		ТекстОбъектов = ТекстОбъектов + Символы.ПС;
	КонецЕсли;
	Если НЕ ПустаяСтрока(Ветка.Тэги) Тогда
		МассивТэгов = СтрРазделить(Ветка.Тэги, ",");
		Для Индекс = 0 По МассивТэгов.ВГраница() Цикл
			Тэг = МассивТэгов[Индекс];
			Шаблон = "	%1" + Символы.ПС + "%2" + Символы.ПС + "	%3";
			Если (Индекс + 1)%2 <> 0 И МассивТэгов.Количество() > 1 Тогда
				Шаблон = Символы.ПС + "	%1" + Символы.ПС + "%2" + Символы.ПС + "	%3" + Символы.ПС;
			КонецЕсли;
			ОписаниеТэга = РазметкаКода.Тэги.Описание[Тэг]; // см. ОписаниеТэга
			ТекстОбъектов = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ОписаниеТэга.Начало, ТекстОбъектов, ОписаниеТэга.Конец);
		КонецЦикла;
	КонецЕсли;
	
	Возврат ТекстОбъектов;
	
КонецФункции

&НаСервере
Функция ПолныйПутьМетаданныхОбъекта(ИмяОбъекта)
	
	ЧастиИмени = СтрРазделить(ИмяОбъекта, ".");
	ЧастиИмени[0] = МножественноеЧисло.Получить(ЧастиИмени[0]);
	ЧастиИмени.Вставить(0, "Метаданные");
	ЧастиИмени.Добавить("ПолноеИмя()");
	Возврат СтрСоединить(ЧастиИмени,".");
	
КонецФункции

&НаСервере
Функция ЗаполнитьТэгиОбъектов(РеквизитИмяОбъекта, ОбъектыОбработчика, РазметкаКода, ВнешниеТэги = Неопределено, СортироватьПоТэгам = Истина)
	
	ЭтоИмяПроцедуры = РеквизитИмяОбъекта = "Процедура" ИЛИ РеквизитИмяОбъекта = "Процедура2";
	ТэгиМодуля = РазметкаКода.Тэги.ПоМодулям[РазметкаКода.ИмяМодуля];
	Если ОбъектыОбработчика.Колонки.Найти("Тэги") = Неопределено Тогда
		ОбъектыОбработчика.Колонки.Добавить("Тэги", Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(100)));
	КонецЕсли;
	ЕстьТэгиМодуляОбновления = ОбъектыОбработчика.Колонки.Найти("ТэгиМодуляОбновления") <> Неопределено;
	Если ТэгиМодуля = Неопределено Тогда
		Возврат ОбъектыОбработчика;
	КонецЕсли;
	ЛишниеТэги = Новый Массив;
	ЛишниеТэги = ЛишниеТэгиВОбласти(ВнешниеТэги, РазметкаКода);
	Для Каждого ИспользуемыйОбъект Из ОбъектыОбработчика Цикл
		Тэги = Новый Массив;
		Если ЭтоИмяПроцедуры Тогда
			ИмяПроцедуры = ИспользуемыйОбъект[РеквизитИмяОбъекта];
			ОписаниеТэгов = РазметкаКода.Тэги.ПоОбработчикам.Найти(ИмяПроцедуры, "Процедура");
			Если ОписаниеТэгов <> Неопределено Тогда
				Тэги = СтрРазделить(ОписаниеТэгов.ТэгиМодуляОбновления,",", Ложь);
			КонецЕсли;
			ИмяОбъекта = ИмяОбъектаИзПроцедурыОбработки(ИспользуемыйОбъект[РеквизитИмяОбъекта]);
		Иначе
			ИмяОбъекта = ИспользуемыйОбъект[РеквизитИмяОбъекта];
		КонецЕсли;
		ОписаниеТэгов = РазметкаКода.Тэги.ПоОбъектам.Найти(ИмяОбъекта, "Имя");
		Если ОписаниеТэгов <> Неопределено Тогда
			ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Тэги, СтрРазделить(ОписаниеТэгов.Тэги,",", Ложь), Истина);
		КонецЕсли;
		Если Тэги.Количество() > 0 Тогда
			ТэгиОбъекта = Новый Массив;
			Для Каждого Тэг Из Тэги Цикл
				ЛишнийТэг = ЛишниеТэги.Найти(Тэг) <> Неопределено;
				Если НЕ ЛишнийТэг Тогда
					ТэгиОбъекта.Добавить(Тэг);
				КонецЕсли;
			КонецЦикла;
			ИспользуемыйОбъект.Тэги = СтрСоединить(ТэгиОбъекта, ",");
			Если ЕстьТэгиМодуляОбновления Тогда
				ВнешниеТэги = ИспользуемыйОбъект.Тэги + ?(ПустаяСтрока(ИспользуемыйОбъект.Тэги),"",",") + ИспользуемыйОбъект.ТэгиМодуляОбновления;
				ИспользуемыйОбъект.ТэгиМодуляОбновления = ВнешниеТэги;
			КонецЕсли;
		КонецЕсли;// найдены тэги объекта
	КонецЦикла;
	ПоляСортировки = РеквизитИмяОбъекта;
	Если СортироватьПоТэгам Тогда
		ПоляСортировки = "Тэги," + РеквизитИмяОбъекта;
	КонецЕсли;
	ОбъектыОбработчика.Сортировать(ПоляСортировки);
	
	Возврат ОбъектыОбработчика;
	
КонецФункции

&НаСервере
Функция ЗаполнитьТэгиМодулейПоПодсистемам(МодулиМенеджеров, РазметкаКода)
	
	РеквизитИмяОбъекта = "ИмяОбъекта";
	Если МодулиМенеджеров.Колонки.Найти("ВнешниеТэги") = Неопределено Тогда
		МодулиМенеджеров.Колонки.Добавить("ВнешниеТэги", Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(100)));
	КонецЕсли;
	ВнешниеТэги = Новый Массив;
	ВнешниеТэги = ЛишниеТэгиВОбласти("", РазметкаКода);
	Для Каждого МодульОбъекта Из МодулиМенеджеров Цикл
		ИмяОбъекта = МодульОбъекта[РеквизитИмяОбъекта];
		ОписаниеТэгов = РазметкаКода.Тэги.ПоОбъектам.Найти(ИмяОбъекта, "Имя");
		Если ОписаниеТэгов <> Неопределено Тогда
			ТэгиМодуля = ОбщегоНазначения.СкопироватьРекурсивно(ВнешниеТэги); // Массив - 
			Для Каждого Тэг Из СтрРазделить(ОписаниеТэгов.Тэги,",") Цикл
				ВнешнийТэг = ВнешниеТэги.Найти(Тэг) <> Неопределено;
				Если НЕ ВнешнийТэг Тогда
					ТэгиМодуля.Добавить(Тэг);
				КонецЕсли;
			КонецЦикла;
			МодульОбъекта.ВнешниеТэги = СтрСоединить(ТэгиМодуля, ",");
		КонецЕсли;// найдены тэги объекта
	КонецЦикла;
	МодулиМенеджеров.Сортировать(РеквизитИмяОбъекта);
	
	Возврат МодулиМенеджеров;
	
КонецФункции

&НаСервере
Функция ЛишниеТэгиВОбласти(ВнешниеТэги, РазметкаКода)
	
	ЛишниеТэги = СтрРазделить(ВнешниеТэги, ",", Ложь);
	ВложенныеТэги = Новый Массив;
	Для Каждого ЛишнийТэг Из ЛишниеТэги Цикл
		БиблиотекиТэга = РазметкаКода.Тэги.ПоБиблиотекам.НайтиСтроки(Новый Структура("Тэг",ЛишнийТэг));
		Если БиблиотекиТэга = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		Для Каждого Имя Из БиблиотекиТэга Цикл
			ТэгиВложенныхБиблиотек = РазметкаКода.Тэги.ВложенныхБиблиотек[Имя.Библиотека];
			Если ТэгиВложенныхБиблиотек <> Неопределено Тогда
				ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ВложенныеТэги, ТэгиВложенныхБиблиотек, Истина);
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ЛишниеТэги, ВложенныеТэги, Истина);
	// Тэги вложенной библиотеки не ставим в модуле
	ТэгиВложенныхБиблиотек = РазметкаКода.Тэги.ВложенныхБиблиотек[РазметкаКода.ИмяКонфигурации];
	Если ТэгиВложенныхБиблиотек <> Неопределено И НЕ РазметкаКода.ЭтоМодульМенеджера Тогда
		ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ЛишниеТэги, ТэгиВложенныхБиблиотек, Истина);
	КонецЕсли;
	
	Возврат ЛишниеТэги;
	
КонецФункции

&НаСервере
Функция ИмяОбъектаИзПроцедурыОбработки(ИмяПроцедурыОбработки)
	
	ЧастиИмени = СтрРазделить(ИмяПроцедурыОбработки, ".");
	Если ЧастиИмени.Количество() = 2 Тогда
		ИмяОбъекта = "ОбщийМодуль." + ЧастиИмени[0];
	Иначе
		ЧастиИмени[0] = ЕдинственноеЧисло[ЧастиИмени[0]];
		ЧастиИмени.Удалить(ЧастиИмени.ВГраница());
		ИмяОбъекта = СтрСоединить(ЧастиИмени, ".");
	КонецЕсли;
	
	Возврат ИмяОбъекта;
	
КонецФункции

&НаСервере
Функция СвернутьПоТегам(Обработчики, РазметкаКода) 
	
	ДеревоТэгов = Новый ДеревоЗначений;
	Для Каждого Колонка Из Обработчики.Колонки Цикл
		ДеревоТэгов.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);
	КонецЦикла;
	Если ДеревоТэгов.Колонки.Найти("Тэги") = Неопределено Тогда
		ДеревоТэгов.Колонки.Добавить("Тэги", Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(100)));
	КонецЕсли;
	
	Если НЕ РазметкаКода.УстановитьТэги Тогда
		ВеткаТэга = ДеревоТэгов.Строки.Добавить();
		Для Каждого Обработчик Из Обработчики Цикл
			НоваяСтрока = ВеткаТэга.Строки.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, Обработчик);
		КонецЦикла;
	Иначе
		Вложенность = РазметкаКода.Тэги.Вложенность;
		ВеткаТэга = Неопределено; // СтрокаДереваЗначений -
		Индекс = 0;
		Пока Индекс < Обработчики.Количество() Цикл
			Обработчик = Обработчики[Индекс];
			Если ВеткаТэга = Неопределено ИЛИ ВеткаТэга.Тэги <> Обработчик.Тэги Тогда
				ВеткаТэга = ДеревоТэгов.Строки.Добавить();
				ВеткаТэга.Тэги = Обработчик.Тэги;
				ДобавитьОбработчикиТэга(Индекс, Обработчики, ВеткаТэга, Вложенность);
				Продолжить;
			КонецЕсли;
			НоваяСтрока = ВеткаТэга.Строки.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, Обработчик);
			Индекс = Индекс + 1;
		КонецЦикла;
	КонецЕсли;
	
	Возврат ДеревоТэгов;
	
КонецФункции

&НаСервере
Процедура ДобавитьОбработчикиТэга(Индекс, Обработчики, ВеткаТэга, Вложенность)
	
	ОбщийТэг = Вложенность.Строки.Найти(ВеткаТэга.Тэги,"Тэг",Истина);
	Пока Индекс < Обработчики.Количество() Цикл
		Обработчик = Обработчики[Индекс];
		Если ВеткаТэга.Тэги <> Обработчик.Тэги Тогда
			Если ОбщийТэг = Неопределено
				ИЛИ ОбщийТэг.Строки.Найти(Обработчик.Тэги) = Неопределено Тогда
				Прервать;
			КонецЕсли;
			ВложеннаяВеткаТэга = ВеткаТэга.Строки.Добавить();
			ВложеннаяВеткаТэга.Тэги = Обработчик.Тэги;
			ДобавитьОбработчикиТэга(Индекс, Обработчики, ВложеннаяВеткаТэга, Вложенность);
			Продолжить;
		КонецЕсли;
		НоваяСтрока = ВеткаТэга.Строки.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, Обработчик);
		Индекс = Индекс + 1;
	КонецЦикла;
	
КонецПроцедуры

// Параметры:
//   ИмяПроцедуры - Строка
//   ТекстПроцедуры - Строка
//   РазметкаКода - Структура:
//   * Тэги - см. ПолучитьСведенияОТегахВырезки
//   * ИмяПроцедуры - Строка
//   * ДобавитьОбластьОписания - Булево
//   * ЭтоМодульМенеджера - Булево
//   * ТэгиЛокализации - Строка
//
&НаСервере
Процедура ПоместитьВПроцедуру(ИмяПроцедуры, ТекстПроцедуры, РазметкаКода)
	
	Если РазметкаКода.УстановитьТэги И РазметкаКода.МодульЛокализации И НЕ РазметкаКода.ЭтоПроцедураОписания Тогда
		ТэгЛокализации = РазметкаКода.Тэги.Описание[РазметкаКода.ТэгиЛокализации]; // см. ОписаниеТэга
		Если ТэгЛокализации <> Неопределено Тогда
			Шаблон = "%1
			|%2
			|%3";
			ТекстПроцедуры = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ТэгЛокализации.Начало, ТекстПроцедуры, ТэгЛокализации.Конец);
		КонецЕсли;
	КонецЕсли;
	
	ТекстПроцедуры = 
	"Процедура " + ИмяПроцедуры + "(Обработчики) Экспорт
	|
	|"+ ТекстПроцедуры +"
	|
	|КонецПроцедуры";
	
КонецПроцедуры

#КонецОбласти

#Область СведенияОТегахВырезки

// Параметры:
//   Настройки - Произвольный
// Возвращаемое значение:
//   Структура:
//   * ПоОбъектам - ТаблицаЗначений
//   * ПоБиблиотекам - ТаблицаЗначений
//   * ПоМодулям - Соответствие
//   * Описание - Строка
//   * РасширениеБиблиотеки - Структура
//   * БиблиотекиСтрокой - Строка
//   * Порядок - Массив
//   * ВложенныхБиблиотек - Соответствие
//   * Вложенность - ДеревоЗначений:
//   ** Тэг - Строка
//   * ПоМодулям - Соответствие
//
&НаСервере
Функция ПолучитьСведенияОТегахВырезки(Настройки)
	
	СведенияОБиблиотеках = ПолучитьСведенияОБиблиотеках(Настройки);
	
	ОбъектыБиблиотек = СведенияОБиблиотеках.ОбъектыБиблиотек;
	ТэгиБиблиотек = СведенияОБиблиотеках.ТэгиБиблиотек;
	БиблиотекиСтрокой = СведенияОБиблиотеках.БиблиотекиСтрокой;
	РасширениеБиблиотеки = СведенияОБиблиотеках.РасширениеБиблиотеки;
	
	ТэгиОбъектов = ОбъектыБиблиотек.СкопироватьКолонки(); // ТаблицаЗначений - 
	ТипСтрока100 = Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(100));
	ТэгиОбъектов.Колонки.Добавить("Тэги", ТипСтрока100);
	ОписаниеТэгов = ПолучитьОписаниеИПорядокТэгов(Настройки);
	ПорядокТэгов = Настройки.ОписаниеТэгов["OrderTags"];
	
	ВсеБиблиотеки = СтрРазделить(БиблиотекиСтрокой, ",",Ложь);
	ВсегоКонфигураций = ВсеБиблиотеки.Количество();
	Для Каждого ОбъектБиблиотеки Из ОбъектыБиблиотек Цикл
		Если ОбъектБиблиотеки.ВсегоВхождений = ВсегоКонфигураций Тогда
			Продолжить;
		КонецЕсли;
		
		ИсключитьИзСтрокой = "";
		Для Каждого ИмяБиблиотеки Из ВсеБиблиотеки Цикл
			Расширяемая = РасширениеБиблиотеки[ИмяБиблиотеки];
			Если НЕ ОбъектБиблиотеки[ИмяБиблиотеки] Тогда
				ИсключитьИзСтрокой = ИсключитьИзСтрокой + ?(НЕ ПустаяСтрока(ИсключитьИзСтрокой), ",", "") + ИмяБиблиотеки;
				Если Расширяемая <> Неопределено Тогда
					Если ТипЗнч(Расширяемая) = Тип("Массив") Тогда
						Для Каждого стр Из Расширяемая Цикл
							ИсключитьИзСтрокой = СтрЗаменить(ИсключитьИзСтрокой, стр, ИмяБиблиотеки);
						КонецЦикла;
					Иначе
						ИсключитьИзСтрокой = СтрЗаменить(ИсключитьИзСтрокой, Расширяемая, ИмяБиблиотеки);
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
		
		ТэгиОбъекта = Новый Массив;
		ИсключитьИзКонфигурации = ОбщегоНазначенияКлиентСервер.СвернутьМассив(СтрРазделить(ИсключитьИзСтрокой, ",",Ложь));
		Для Каждого ИмяБиблиотеки Из ИсключитьИзКонфигурации Цикл
			Отбор = Новый Структура("Библиотека", ИмяБиблиотеки);
			НайденныеТэги = ТэгиБиблиотек.НайтиСтроки(Отбор);
			Для Каждого Строка Из НайденныеТэги Цикл 
				ТэгиОбъекта.Добавить(Строка.Тэг);
			КонецЦикла;
		КонецЦикла;
		
		УстановитьПорядокТэгов(ТэгиОбъекта, ПорядокТэгов);
		
		НоваяСтрока = ТэгиОбъектов.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, ОбъектБиблиотеки);
		НоваяСтрока.Тэги = СтрСоединить(ТэгиОбъекта, ",");
		
	КонецЦикла;
	
	ТэгиМодулей = Новый Соответствие;
	Для Каждого Описание Из Настройки.ОписаниеТэгов["configurations"] Цикл
		Модуль = Описание.Значение["module"];
		Если Модуль = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		ТэгиМодуля = Описание.Значение["outTags"];
		Если ТэгиМодуля <> Неопределено Тогда
			ТэгиМодулей.Вставить(Модуль, ТэгиМодуля);
		КонецЕсли;
	КонецЦикла;
	
	
	Тэги = Новый Структура;
	Тэги.Вставить("ПоОбъектам", ТэгиОбъектов);
	Тэги.Вставить("ПоБиблиотекам", ТэгиБиблиотек);
	Тэги.Вставить("ПоМодулям", ТэгиМодулей);
	Тэги.Вставить("Описание", ОписаниеТэгов);
	Тэги.Вставить("РасширениеБиблиотеки", РасширениеБиблиотеки);
	Тэги.Вставить("БиблиотекиВПорядкеВложенности", СведенияОБиблиотеках.БиблиотекиВПорядкеВложенности);
	Тэги.Вставить("БиблиотекиСтрокой", БиблиотекиСтрокой);
	Тэги.Вставить("Порядок", ПорядокТэгов);
	ДеревоТэгов = Новый ДеревоЗначений;
	ДеревоТэгов.Колонки.Добавить("Тэг", ТипСтрока100);
	Тэги.Вставить("Вложенность", ДеревоТэгов);
	
	ВложенныхБиблиотек = Новый Соответствие;
	Для Каждого Расширение Из РасширениеБиблиотеки Цикл
		ТэгиВложеннойБиблиотеки = Новый Массив;
		ДобавитьТэгиВложенныхБиблиотек(ТэгиВложеннойБиблиотеки, Расширение.Ключ, Тэги);
		ВложенныхБиблиотек.Вставить(Расширение.Ключ, ТэгиВложеннойБиблиотеки);
		
		Тэг = ТэгБиблиотеки(Расширение.Значение, ТэгиБиблиотек);
		Если НЕ ПустаяСтрока(Тэг) Тогда
			ВеткаТэга = ДеревоТэгов.Строки.Добавить();
			ВеткаТэга.Тэг = Тэг;
			Тэг = ТэгБиблиотеки(Расширение.Ключ, ТэгиБиблиотек);
			Если НЕ ПустаяСтрока(Тэг) Тогда
				ВложенныйТэг = ВеткаТэга.Строки.Добавить();
				ВложенныйТэг.Тэг = Тэг;
				ДобавитьВложенныеТэги(ВложенныйТэг, Расширение.Ключ, Тэги);
			КонецЕсли;
			Если ВеткаТэга.Строки.Количество() = 0 Тогда
				ДеревоТэгов.Строки.Удалить(ВеткаТэга);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	Тэги.Вставить("ВложенныхБиблиотек", ВложенныхБиблиотек);
	
	Возврат Тэги;
	
КонецФункции

&НаСервере
Процедура ДобавитьВложенныеТэги(ВеткаТэга, ИмяБиблиотеки, ОписаниеТэгов)
	
	БиблиотекаВхождения = Неопределено;
	Для Каждого Расширение Из ОписаниеТэгов.РасширениеБиблиотеки Цикл
		Если ИмяБиблиотеки = Расширение.Значение Тогда
			БиблиотекаВхождения = Расширение.Ключ;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Если БиблиотекаВхождения <> Неопределено Тогда
		Тэг = ТэгБиблиотеки(БиблиотекаВхождения, ОписаниеТэгов.ПоБиблиотекам);
		Если НЕ ПустаяСтрока(Тэг) Тогда
			ВложенныйТэг = ВеткаТэга.Строки.Добавить();
			ВложенныйТэг.Тэг = Тэг;
			ДобавитьВложенныеТэги(ВложенныйТэг, БиблиотекаВхождения, ОписаниеТэгов);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Функция ТэгБиблиотеки(Библиотека, ТэгиБиблиотек)
	
	Результат = "";
	НайденнаяСтрока = ТэгиБиблиотек.Найти(Библиотека, "Библиотека");
	Если НайденнаяСтрока <> Неопределено Тогда
		Результат = НайденнаяСтрока.Тэг;
	КонецЕсли;
	Возврат Результат;
	
КонецФункции

&НаСервере
Процедура УстановитьПорядокТэгов(Тэги, ПорядокТэгов)
	
	УпорядоченныйРезультат = Новый Массив;
	Для Каждого ТэгПоПорядку Из ПорядокТэгов Цикл
		
		Если Тэги.Найти(ТэгПоПорядку) <> Неопределено Тогда
			УпорядоченныйРезультат.Добавить(ТэгПоПорядку);
		КонецЕсли;
		
	КонецЦикла;
	
	Тэги = УпорядоченныйРезультат;
	
КонецПроцедуры

&НаСервере
Процедура ДобавитьТэгиВложенныхБиблиотек(Тэги, ИмяБиблиотеки, ОписаниеТэгов)
	
	ВложеннаяБиблиотека = ОписаниеТэгов.РасширениеБиблиотеки[ИмяБиблиотеки];
	Если ВложеннаяБиблиотека <> Неопределено Тогда
		Отбор = Новый Структура("Библиотека", ВложеннаяБиблиотека);
		НайденныеСтроки = ОписаниеТэгов.ПоБиблиотекам.НайтиСтроки(Отбор);
		Для Каждого Строка Из НайденныеСтроки Цикл
			Тэги.Добавить(Строка.Тэг);
		КонецЦикла;
		ДобавитьТэгиВложенныхБиблиотек(Тэги, ВложеннаяБиблиотека, ОписаниеТэгов);
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//   Настройки - Произвольный
// Возвращаемое значение:
//   КлючИЗначение - Описание:
//   * Ключ - Строка - наименование тэга
//   * Значение - см. ОписаниеТэга
//
&НаСервере
Функция ПолучитьОписаниеИПорядокТэгов(Настройки)
	
	Тэги = Новый Соответствие;
	Если Настройки.ОписаниеТэгов["tags"] <> Неопределено Тогда
		ПорядокТэгов = Новый Массив;
		Для Каждого Описание Из Настройки.ОписаниеТэгов["tags"] Цикл
			
			ГраницыТэга = ОписаниеТэга();
			ГраницыТэга.Начало = Описание["begin"];
			ГраницыТэга.Конец = Описание["end"];
			Тэги.Вставить(Описание["id"], ГраницыТэга);
			ПорядокТэгов.Добавить(Описание["id"]);
			
		КонецЦикла;
		Настройки.ОписаниеТэгов.Вставить("OrderTags", ПорядокТэгов);
	КонецЕсли;
	
	Возврат Тэги;
	
КонецФункции

// Возвращаемое значение:
//   Структура:
//   * Начало - Строка
//   * Конец - Строка
//
&НаСервере
Функция ОписаниеТэга()
	
	Возврат Новый Структура("Начало, Конец");
	
КонецФункции

&НаСервере
Функция ПолучитьСведенияОБиблиотеках(Настройки)
	
	ТипСтрока100 = Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(100));
	ТипСтрока300 = Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(300));
	ТипЧисло10 = Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(10, 0));
	
	ТэгиБиблиотек = Новый ТаблицаЗначений;
	ТэгиБиблиотек.Колонки.Добавить("Библиотека", ТипСтрока100);
	ТэгиБиблиотек.Колонки.Добавить("Тэг", ТипСтрока100);
	
	ТипБулево = Новый ОписаниеТипов("Булево");
	ТипСтрока300 = Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(300));
	
	ОбъектыБиблиотек = Новый ТаблицаЗначений;
	ОбъектыБиблиотек.Колонки.Добавить("Имя", ТипСтрока300);
	ОбъектыБиблиотек.Колонки.Добавить("ВсегоВхождений", ТипЧисло10);
	Для Каждого Имя Из Настройки.ВсеОбъекты Цикл
		НоваяСтрока = ОбъектыБиблиотек.Добавить();
		НоваяСтрока.Имя = Имя;
	КонецЦикла;
	
	БиблиотекиСтрокой = "";
	РасширениеБиблиотеки = Новый Соответствие;
	Если Настройки.ОписаниеТэгов["configurations"] <> Неопределено Тогда
		Для Каждого Библиотека Из Настройки.ОписаниеТэгов["configurations"] Цикл
			
			ВложеннаяБиблиотека = Библиотека.Значение["extends"];
			Если ВложеннаяБиблиотека <> Неопределено Тогда
				РасширениеБиблиотеки.Вставить(Библиотека.Ключ, ВложеннаяБиблиотека);
			КонецЕсли;
			
			Содержимое = Библиотека.Значение["content"];
			Если НЕ ЗначениеЗаполнено(Содержимое) Тогда
				Продолжить;
			КонецЕсли;
			
			ТэгиВырезки = Библиотека.Значение["outTags"];
			Если ТэгиВырезки = Неопределено Тогда
				Продолжить;
			КонецЕсли;
			
			ИмяМодуля = Библиотека.Значение["module"];
			Если НЕ ЗначениеЗаполнено(ИмяМодуля) Тогда
				Продолжить;
			КонецЕсли;
			
			Если ОбъектыБиблиотек.Колонки.Найти(Библиотека.Ключ) = Неопределено Тогда
				ОбъектыБиблиотек.Колонки.Добавить(Библиотека.Ключ, ТипБулево);
				БиблиотекиСтрокой = БиблиотекиСтрокой + ?(БиблиотекиСтрокой <> "", ",","") + Библиотека.Ключ;
			КонецЕсли;
			
			Для Каждого Тэг Из ТэгиВырезки Цикл
				НовыйТэг = ТэгиБиблиотек.Добавить();
				НовыйТэг.Библиотека = Библиотека.Ключ;
				НовыйТэг.Тэг = Тэг;
			КонецЦикла;
			Объекты = Библиотека.Значение["Объекты"];
			Для Каждого ИмяОбъекта Из Объекты Цикл
				НоваяСтрока = ОбъектыБиблиотек.Добавить();
				НоваяСтрока.Имя = ИмяОбъекта.Ключ;
				НоваяСтрока.ВсегоВхождений = 1;
				НоваяСтрока[Библиотека.Ключ] = Истина;
			КонецЦикла;
		
		КонецЦикла;
	КонецЕсли;
	ВложенностьБиблиотек = ОпределитьВложенностьБиблиотек(РасширениеБиблиотеки);
	ОбщегоНазначенияКлиентСервер.ДополнитьМассив(ВложенностьБиблиотек, СтрРазделить(БиблиотекиСтрокой, ","), Истина);
	
	ОбъектыБиблиотек.Свернуть("Имя", "ВсегоВхождений," + БиблиотекиСтрокой);
	ОбъектыБиблиотек.Сортировать("Имя, ВсегоВхождений УБЫВ");
	ОбъектыБиблиотек.Индексы.Добавить("Имя");
	
	ТэгиБиблиотек.Сортировать("Библиотека, Тэг");
	ТэгиБиблиотек.Индексы.Добавить("Библиотека");
	
	Результат = Новый Структура;
	Результат.Вставить("ОбъектыБиблиотек", ОбъектыБиблиотек);
	Результат.Вставить("ТэгиБиблиотек", ТэгиБиблиотек);
	Результат.Вставить("БиблиотекиСтрокой", БиблиотекиСтрокой);
	Результат.Вставить("РасширениеБиблиотеки", РасширениеБиблиотеки);
	Результат.Вставить("БиблиотекиВПорядкеВложенности", ВложенностьБиблиотек);
	
	Возврат Результат
	
КонецФункции

&НаСервере
Процедура ОпределитьТэгиДляОбъектовНеВходящихВКонфигурацию(ОписаниеТэгов)
	
	ТэгиРасширители = ТэгиРасширители(ОписаниеТэгов);
	Для Каждого Описание Из ОписаниеТэгов["configurations"] Цикл
		Описание.Значение.Вставить("outTags", Новый Массив);
		ТэгиВырезки = Описание.Значение["outTags"]; // Массив - 
		
		Тэги = Описание.Значение["tags"];
		Если Тэги <> Неопределено Тогда
			Расширители = ТэгиРасширители[Описание.Ключ];
			Если Расширители = Неопределено Тогда
				Расширители = Новый Массив; 
			КонецЕсли;
			Для Каждого Тэг Из Тэги Цикл
				Индекс = Расширители.Найти(Тэг);
				Если Индекс = Неопределено Тогда
					ТэгиВырезки.Добавить(Тэг);
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Функция ОпределитьВложенностьБиблиотек(СвязанныйСписок)
	
	Вложенность = Новый ТаблицаЗначений;
	Вложенность.Колонки.Добавить("Библиотека", Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(100)));
	Вложенность.Колонки.Добавить("ВсегоВхождений", Новый ОписаниеТипов("Число",Новый КвалификаторыЧисла(10, 0)));
	Для Каждого Уровень Из СвязанныйСписок Цикл
	
		НоваяСтрока = Вложенность.Добавить();
		НоваяСтрока.Библиотека = Уровень.Значение;
		НоваяСтрока.ВсегоВхождений = 1;
		
		ДобавитьВложенную(Уровень.Значение, Вложенность, СвязанныйСписок);
		
		Если Вложенность.Найти(Уровень.Ключ,"Библиотека")= Неопределено Тогда
			НоваяСтрока = Вложенность.Добавить();
			НоваяСтрока.Библиотека = Уровень.Ключ;
			НоваяСтрока.ВсегоВхождений = 0;
		КонецЕсли;
		
	КонецЦикла;
	Вложенность.Свернуть("Библиотека","ВсегоВхождений");
	Вложенность.Сортировать("ВсегоВхождений УБЫВ");
	
	Возврат Вложенность.ВыгрузитьКолонку("Библиотека");
	
КонецФункции

&НаСервере
Процедура ДобавитьВложенную(Родитель, Вложенность, СвязанныйСписок, НомерУровня = 1)
	
	ВложеннаяСтрока = СвязанныйСписок[Родитель];
	
	Если ВложеннаяСтрока <> Неопределено Тогда
		ДобавитьВложенную(ВложеннаяСтрока, Вложенность, СвязанныйСписок, НомерУровня+1);
	КонецЕсли;
	НоваяСтрока = Вложенность.Добавить();
	НоваяСтрока.Библиотека = Родитель;
	НоваяСтрока.ВсегоВхождений = НомерУровня;
	
КонецПроцедуры

&НаСервере
Функция ТэгиРасширители(ОписаниеТэгов)
	
	ТэгиРасширители = Новый Соответствие;
	Для Каждого Описание Из ОписаниеТэгов["configurations"] Цикл
		РасширяемаяКонфигурация = Описание.Значение["extends"];
		Если РасширяемаяКонфигурация <> Неопределено Тогда
			Тэги = Описание.Значение["tags"];
			Если Тэги <> Неопределено Тогда
				Конфигурация = ТэгиРасширители[РасширяемаяКонфигурация];
				Если Конфигурация = Неопределено Тогда
					ТэгиРасширители.Вставить(РасширяемаяКонфигурация, Тэги);
				Иначе
					ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Конфигурация, Тэги, Истина);
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Возврат ТэгиРасширители;
	
КонецФункции

#КонецОбласти

#Область СоставКонфигурации

&НаКлиенте
Функция ПолучитьВсеОбъектыИсходнойКонфигурации()
	
	ИмяФайла = Объект.КаталогSRC + "Configuration\Configuration.mdo";
	ВсеОбъекты = Новый Массив;
	
	ФайлПодсистемы = Новый Файл(ИмяФайла);
	Если НЕ ФайлПодсистемы.Существует() Тогда
		Возврат ВсеОбъекты;
	КонецЕсли;
	
	ИмяКлассаRU = РусскиеИменаКлассов();
	
	Тэги = Новый Массив;
	Тэги.Добавить("accountingRegisters");
	Тэги.Добавить("accumulationRegisters");
	Тэги.Добавить("businessProcesses");
	Тэги.Добавить("calculationRegisters");
	Тэги.Добавить("catalogs");
	Тэги.Добавить("chartsOfAccounts");
	Тэги.Добавить("chartsOfCalculationTypes");
	Тэги.Добавить("chartsOfCharacteristicTypes");
	Тэги.Добавить("constants");
	Тэги.Добавить("commonModules");
	Тэги.Добавить("documents");
	Тэги.Добавить("informationRegisters");
	Тэги.Добавить("reports");
	Тэги.Добавить("tasks");
	
	#Если НЕ ВебКлиент Тогда
	Текст = Новый ЧтениеТекста;
	Текст.Открыть(ИмяФайла, КодировкаТекста.UTF8);
	
	СтрокаФайла = Текст.ПрочитатьСтроку();
	Пока СтрокаФайла <> Неопределено Цикл
		
		СтрокаФайла = Текст.ПрочитатьСтроку();
		Тэг = НайтиТэг(СтрокаФайла, Тэги);
		Если Тэг <> Неопределено Тогда
			
			СтрокаФайла = СтрЗаменить(СтрокаФайла, "<"+Тэг+">", "");
			ИмяОбъекта = СокрЛП(СтрЗаменить(СтрокаФайла, "</"+Тэг+">", ""));
			
			ЧастиИмени = СтрРазделить(ИмяОбъекта, ".");
			ЧастиИмени[0] = ИмяКлассаRU[ЧастиИмени[0]];
			
			ВсеОбъекты.Добавить(СтрСоединить(ЧастиИмени, "."));
			
		КонецЕсли;
		
	КонецЦикла;
	#КонецЕсли
	
	Возврат ВсеОбъекты;
	
КонецФункции

&НаКлиенте
Функция НайтиТэг(СтрокаФайла, Тэги)
	
	Для Каждого Тэг Из Тэги Цикл
		Если СтрНайти(СтрокаФайла, Тэг) > 0 Тогда
			 Возврат Тэг;
		КонецЕсли;
	КонецЦикла;
	Возврат Неопределено;
	
КонецФункции

#КонецОбласти

#Область СоставПодсистемы
&НаКлиенте
Процедура ПолучитьОбъектыПодсистем(ОписаниеКонфигураций)
	
	РусскиеИменаКлассов = РусскиеИменаКлассов();
	Для Каждого Описание Из ОписаниеКонфигураций Цикл
		ОбъектыПодсистемы = Новый Соответствие;
		Подсистемы = Описание.Значение["content"];
		Если ЗначениеЗаполнено(Подсистемы) Тогда
			Для Каждого Подсистема Из Подсистемы Цикл
				ДобавитьОбъектыПодсистемы(ОбъектыПодсистемы, Подсистема, РусскиеИменаКлассов);
			КонецЦикла;
		КонецЕсли;
		ПодсистемыИсключения = Описание.Значение["except_content"];
		Если ЗначениеЗаполнено(ПодсистемыИсключения) Тогда
			ОбъектыИсключения = Новый Соответствие;
			Для Каждого Подсистема Из ПодсистемыИсключения Цикл
				ДобавитьОбъектыПодсистемы(ОбъектыИсключения, Подсистема, РусскиеИменаКлассов);
			КонецЦикла;
			Для Каждого ОбъектИсключения Из ОбъектыИсключения Цикл
				ОбъектыПодсистемы.Удалить(ОбъектИсключения.Ключ);
			КонецЦикла;
		КонецЕсли;
		
		Описание.Значение.Вставить("Объекты", ОбъектыПодсистемы);
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьОбъектыПодсистемы(ОбъектыКонфигурации, Подсистема, РусскиеИменаКлассов)
	
	ЧастиИмени = СтрРазделить(Подсистема, ".");
	ЧастьПути = "Subsystems\" + СтрСоединить(ЧастиИмени, "\Subsystems\");
	ИмяФайла = Объект.КаталогSRC + ЧастьПути + "\" + ЧастиИмени[ЧастиИмени.ВГраница()] + ".mdo";
	ФайлПодсистемы = Новый Файл(ИмяФайла);
	
	Если НЕ ФайлПодсистемы.Существует() Тогда
		Возврат;
	КонецЕсли;
	
	#Если НЕ ВебКлиент Тогда
	Текст = Новый ЧтениеТекста;
	Текст.Открыть(ИмяФайла, КодировкаТекста.UTF8);
	
	СтрокаФайла = Текст.ПрочитатьСтроку();
	Пока СтрокаФайла <> Неопределено Цикл
		
		Если СтрНайти(СтрокаФайла, "<content>") > 0 Тогда
			СтрокаФайла = СокрЛП(СтрЗаменить(СтрокаФайла, "<content>", ""));
			СтрокаФайла = СокрЛП(СтрЗаменить(СтрокаФайла, "</content>", ""));
			ЧастиИмени = СтрРазделить(СтрокаФайла, ".");
			ЧастиИмени[0] = РусскиеИменаКлассов[ЧастиИмени[0]];
			Если ЧастиИмени[0] <> Неопределено Тогда
				ИмяОбъекта = СтрСоединить(ЧастиИмени, ".");
				ОбъектыКонфигурации.Вставить(ИмяОбъекта, ИмяОбъекта);
			КонецЕсли;
			
		ИначеЕсли СтрНайти(СтрокаФайла, "<subsystems>") > 0 Тогда
			СтрокаФайла = СокрЛП(СтрЗаменить(СтрокаФайла, "<subsystems>", ""));
			СтрокаФайла = СокрЛП(СтрЗаменить(СтрокаФайла, "</subsystems>", ""));
			ЧастиИмени = Новый Массив;
			ЧастиИмени.Добавить(Подсистема);
			ЧастиИмени.Добавить(СтрокаФайла);
			ИмяВложеннойПодсистемы = СтрСоединить(ЧастиИмени, ".");
			ДобавитьОбъектыПодсистемы(ОбъектыКонфигурации, ИмяВложеннойПодсистемы, РусскиеИменаКлассов);
		КонецЕсли;
		
		СтрокаФайла = Текст.ПрочитатьСтроку();
		
	КонецЦикла;
	#КонецЕсли
	
КонецПроцедуры

&НаКлиенте
// Возвращает соответствие английских имен русским для обрабатываемых классов объектов метаданных.
Функция РусскиеИменаКлассов()
	
	Результат = Новый Соответствие;
	
	Результат.Вставить("AccountingRegister", "РегистрБухгалтерии");
	Результат.Вставить("AccumulationRegister", "РегистрНакопления");
	Результат.Вставить("BusinessProcess", "БизнесПроцесс");
	Результат.Вставить("CalculationRegister", "РегистрРасчета");
	Результат.Вставить("Catalog", "Справочник");
	Результат.Вставить("ChartOfAccounts", "ПланСчетов");
	Результат.Вставить("ChartOfCalculationTypes", "ПланВидовРасчета");
	Результат.Вставить("ChartOfCharacteristicTypes", "ПланВидовХарактеристик");
	Результат.Вставить("Constant", "Константа");
	Результат.Вставить("CommonModule", "ОбщийМодуль");// указываются в приоритетах других обработчиков
	Результат.Вставить("Document", "Документ");
	Результат.Вставить("ExchangePlan", "ПланОбмена");
	Результат.Вставить("InformationRegister", "РегистрСведений");
	Результат.Вставить("Task", "Задача");
	Результат.Вставить("Sequence", "Последовательность");
	Результат.Вставить("Report", "Отчет");// указываются в блокируемых объектах
	
	Возврат Результат;
	
КонецФункции

#КонецОбласти

#Область ЧтениеYAML
&НаКлиенте
Функция ПрочитатьФайлYaml(ИмяФайла)
	
	Результат = Новый Соответствие;
	
	Файл = Новый Файл(ИмяФайла);
	Если НЕ Файл.Существует() Тогда
		Шаблон = НСтр("ru = 'Не обнаружен файл настроек ""%1""'");
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ИмяФайла);
	КонецЕсли;
	
	#Если НЕ ВебКлиент Тогда
	ТекстФайла = Новый ТекстовыйДокумент;
	ТекстФайла.Прочитать(ИмяФайла, КодировкаТекста.UTF8);
	Попытка
		
		ПрочитатьСтрокиYAML(Результат, ТекстФайла);
		
	Исключение
		ТекстОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ТекстСообщения = Символы.ПС + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Не удалось прочитать файл %1.'"), ИмяФайла);
		ТекстСообщения = ТекстСообщения  + Символы.ПС + НСтр("ru = 'По причине'")+":" + Символы.ПС;
		ТекстСообщения = ТекстСообщения  + ТекстОшибки;
		ВызватьИсключение ТекстСообщения;
	КонецПопытки;
	#КонецЕсли
	
	Возврат Результат;
	
КонецФункции

&НаКлиенте
Процедура ПрочитатьСтрокиYAML(Результат, ТекстФайла, НомерСтроки = 0, Уровень = 0, ЧтениеМногострочнойСтроки = Ложь)
	
	Попытка
		ВсегоСтрок = ТекстФайла.КоличествоСтрок();
		Пока НомерСтроки <= ВсегоСтрок Цикл
			
			НомерСтроки = НомерСтроки + 1;
			СтрокаФайла = ТекстФайла.ПолучитьСтроку(НомерСтроки);
			Если СокрЛП(СтрокаФайла) = "" И НЕ ЧтениеМногострочнойСтроки ИЛИ Лев(СокрЛП(СтрокаФайла), 1) = "#" Тогда
				Продолжить;
			КонецЕсли;
			
			Параметр = ЗначениеИзСтрокиYaml(СтрокаФайла);
			Если Параметр.Уровень < Уровень Тогда
				НомерСтроки = НомерСтроки - 1;
				Прервать;
			КонецЕсли;
			
			Если Параметр.ЭлементМассива Тогда
				Если ТипЗнч(Результат) <> Тип("Массив") Тогда
					Результат = Новый Массив;
				КонецЕсли;
				Если ПустаяСтрока(Параметр.Ключ) Тогда
					ДобавитьВРезультатYAML(Результат, Параметр);
				Иначе
					Результат.Добавить(Новый Соответствие);
					ДобавитьВРезультатYAML(Результат[Результат.ВГраница()], Параметр);
					ПрочитатьСтрокиYAML(Результат[Результат.ВГраница()], ТекстФайла, НомерСтроки, Параметр.Уровень+1);
				КонецЕсли;
				
			ИначеЕсли Параметр.Значение = "|" Тогда
				Параметр.Значение = "";
				ПрочитатьСтрокиYAML(Параметр.Значение, ТекстФайла, НомерСтроки, Параметр.Уровень+1, Истина);
				ДобавитьВРезультатYAML(Результат, Параметр);
				
			ИначеЕсли НЕ ЗначениеЗаполнено(Параметр.Значение) Тогда
				
				ПрочитатьСтрокиYAML(Параметр.Значение, ТекстФайла, НомерСтроки, Параметр.Уровень+1);
				ДобавитьВРезультатYAML(Результат, Параметр);
				
			Иначе
				ДобавитьВРезультатYAML(Результат, Параметр);
				
			КонецЕсли;
			
		КонецЦикла;
	
	Исключение
		ТекстОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ТекстСообщения = Символы.ПС + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Не удалось разобрать строку: %1'"), СтрокаФайла);
		ТекстСообщения = ТекстСообщения  + Символы.ПС + НСтр("ru = 'По причине'")+":" + Символы.ПС;
		ТекстСообщения = ТекстСообщения  + ТекстОшибки;
		ВызватьИсключение ТекстСообщения;
	КонецПопытки;
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьВРезультатYAML(Результат, Параметр)
	
	Если ЗначениеЗаполнено(Параметр.Ключ) И ТипЗнч(Результат) <> Тип("Соответствие") Тогда
		Результат = Новый Соответствие;
	КонецЕсли;
	
	Если ТипЗнч(Результат) = Тип("Соответствие") Тогда
		Результат.Вставить(Параметр.Ключ, Параметр.Значение);
		
	ИначеЕсли ТипЗнч(Результат) = Тип("Массив") Тогда
		Результат.Добавить(Параметр.Значение);
		
	ИначеЕсли ТипЗнч(Результат) = Тип("Строка") Тогда
		Результат = Результат + Параметр.Значение + Символы.ПС;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Функция ЗначениеИзСтрокиYaml(Знач СтрокаYaml)
	
	Ключ = "";
	Значение = Неопределено;
	
	СтрокаБезОтступа = СокрЛ(СтрокаYaml);
	Отступ = СтрНайти(СтрокаYaml,СтрокаБезОтступа)-1;
	Уровень = Отступ;
	ЭлементМассива = Ложь;
	
	СтрокаYaml = СокрЛП(СтрокаYaml);
	Если Лев(СтрокаYaml,1) = "-" Тогда
		ЭлементМассива = Истина;
		Уровень = Уровень + 1;
		СтрокаYaml = СокрЛП(Прав(СтрокаYaml, СтрДлина(СтрокаYaml)-1));
	КонецЕсли;
	
	Двоеточие = СтрНайти(СтрокаYaml,":");
	Если Двоеточие <> 0 И Сред(СтрокаYaml, Двоеточие, 2) <> ":\" И Сред(СтрокаYaml, Двоеточие, 2) <> ":/" Тогда
		Ключ     = СокрЛП(Лев(СтрокаYaml,  Двоеточие - 1));
		Значение = СокрЛП(Сред(СтрокаYaml, Двоеточие + 1));
		
	Иначе
		Значение = СтрокаYaml;
		
	КонецЕсли;
	
	Решетка = СтрНайти(Значение, "#");
	Если Решетка <> 0 Тогда
		Значение = СокрЛП(Лев(Значение,  Решетка - 1));
	КонецЕсли;
	
	Результат = Новый Структура("Ключ,Значение,Уровень", Ключ,Значение,Уровень);
	Результат.Вставить("ЭлементМассива", ЭлементМассива);
	Возврат Результат;
	
КонецФункции
#КонецОбласти

#КонецОбласти

#Область ТестПостроенияОчереди

&НаКлиенте
Процедура ЗаписатьОшибку(ИмяОбъекта, ОписаниеОшибки = "",
                         ИнформацияОбОшибке = Неопределено, Ключ = Неопределено)
	 
	Ошибка = СоздатьОписаниеОшибки();
	Ошибка.ТипОшибки              = НСтр("ru = 'Ошибка построения очереди отложенных обработчиков обновления'");
	Ошибка.ПорядокВоспроизведения = ОписаниеОшибки;
	Ошибка.ОбъектМетаданных       = ИмяОбъекта;
	
	Если ИнформацияОбОшибке <> Неопределено Тогда
		Ошибка.ИсходнаяИнформация   = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
	КонецЕсли; 
	
	Если ЗначениеЗаполнено(ДополнениеТекстаОшибки) Тогда
		Ошибка.ПорядокВоспроизведения = Ошибка.ПорядокВоспроизведения + Символы.ПС + ДополнениеТекстаОшибки;
	КонецЕсли; 
	Если ЗначениеЗаполнено(ДатаОбнаруженияОшибки) Тогда
		Ошибка.ДатаОбнаружения = ДатаОбнаруженияОшибки;
	КонецЕсли; 
	Если ЗначениеЗаполнено(АдресРепозитория) Тогда
		Ошибка.АдресРепозитория = АдресРепозитория;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(КаталогФайловОшибок) Тогда
		
		Файл = Новый Файл(КаталогФайловОшибок);
		Если НЕ Файл.Существует() Тогда
			СоздатьКаталог(КаталогФайловОшибок);
		ИначеЕсли НЕ Файл.ЭтоКаталог() Тогда
			УдалитьФайлы(КаталогФайловОшибок);
			СоздатьКаталог(КаталогФайловОшибок);
		КонецЕсли; 
		
		ИмяФайлаОшибки = ДобавитьРазделительПутиВКонец(КаталогФайловОшибок);
		ИмяФайлаОшибки = ИмяФайлаОшибки + Формат(ОбщегоНазначенияКлиент.ДатаСеанса(), "ДФ=yyyyMMddHHmmss") 
		               + "_" + Строка(Новый УникальныйИдентификатор())+".xml";
		
		Результат = Новый ТекстовыйДокумент;
		#Если НЕ ВебКлиент Тогда
		Результат.УстановитьТекст(ТекстОшибкиXML(Ошибка));
		#КонецЕсли
		Результат.Записать(ИмяФайлаОшибки);
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция СоздатьОписаниеОшибки() 

	Ошибка = Новый Структура;
	
	Ошибка.Вставить("ВерсияФормата", "1.4");
	Ошибка.Вставить("УИ", Строка(Новый УникальныйИдентификатор));
	Ошибка.Вставить("ТипОшибки", "");
	Ошибка.Вставить("ИсходнаяИнформация", "");
	Ошибка.Вставить("ПорядокВоспроизведения", "");
	Ошибка.Вставить("ОжидаемоеПоведение", "");
	Ошибка.Вставить("Ответственный", "");
	Ошибка.Вставить("ДостоверностьОбнаружения", "Низкая"); // "Высокая" либо "Низкая"
	Ошибка.Вставить("АдресРепозитория", "");
	
	#Если Клиент Или ТолстыйКлиентУправляемоеПриложение Или ТонкийКлиент Или ВебКлиент  Тогда
	
		СисИнфо = Новый СистемнаяИнформация;
		Ошибка.Вставить("ВерсияПлатформы", СисИнфо.ВерсияПриложения);
		Ошибка.Вставить("КлиентОперативнаяПамять", СисИнфо.ОперативнаяПамять);
		Ошибка.Вставить("КлиентВерсияОС", СисИнфо.ВерсияОС);
		Ошибка.Вставить("КлиентПроцессор", СисИнфо.Процессор);
		Ошибка.Вставить("КлиентТипПлатформы", Строка(СисИнфо.ТипПлатформы));
		Ошибка.Вставить("КлиентИнформацияПрограммыПросмотра", СисИнфо.ИнформацияПрограммыПросмотра);
		Ошибка.Вставить("КлиентТекущаяДата", ОбщегоНазначенияКлиент.ДатаСеанса());
	
	#КонецЕсли
	
	Ошибка.Вставить("ДатаОбнаружения",   Дата(1,1,1));
	Ошибка.Вставить("ОбъектыМетаданных", Новый Массив); // Возможность добавить массив объектов метаданных
	// Регистрация по одному объекту метаданных
	Ошибка.Вставить("ОбъектМетаданных", "");
	Ошибка.Вставить("УточнениеРасположения", "");
	Ошибка.Вставить("КодСценария", "");
	Ошибка.Вставить("ИмяСценария", "");
	
	Ошибка.Вставить("ИменаФайлов", Новый Массив);
	
	Возврат Ошибка;
	
КонецФункции

#Если НЕ ВебКлиент Тогда
&НаКлиенте
Функция ТекстОшибкиXML(Ошибка)
	
	Если ЗначениеЗаполнено(Ошибка.ОбъектМетаданных) ИЛИ ЗначениеЗаполнено(Ошибка.УточнениеРасположения) Тогда
		Ошибка.ОбъектыМетаданных.Добавить(Новый Структура("ОбъектМетаданных, УточнениеРасположения", Ошибка.ОбъектМетаданных, Ошибка.УточнениеРасположения));
	КонецЕсли; 
	
	Ошибка.Удалить("ОбъектМетаданных");
	Ошибка.Удалить("УточнениеРасположения");
	
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку();
	
	СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Ошибка);
	
	Возврат ЗаписьXML.Закрыть();
	
КонецФункции
#КонецЕсли

#КонецОбласти

#Область ЗаписьНастроекERP

&НаСервере
Функция ПолучитьТекстыНастроек()
	
	Обработка = ОбъектОбработки();
	ТэгиВырезки = Обработка.ПолучитьМакет("cut_tags");
	
	ТекстыНастроек = Новый СписокЗначений;
	ТекстыНастроек.Добавить(
		ТэгиВырезки.ПолучитьТекст(), 
		НСтр("ru = 'Файл cut_tags.yml сохранить в каталог .settings локальной папки проекта в кодировке UTF-8'"));
	
	Возврат ТекстыНастроек;
	
КонецФункции

#КонецОбласти

#Область УстановитьНомерСборки

&НаКлиенте
Процедура ЗавершениеВводаНомераСборки(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат <> Неопределено И Результат > 0 Тогда
		Если ДополнительныеПараметры.НомерСборкиДляОбработчиков Тогда
			УстановитьНомерСборкиОбработчикамНаСервере(Результат);
		Иначе
			НовыйНомерСборкиКонфигурации = Результат;
		КонецЕсли;
		Модифицированность = Истина;
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура УстановитьНомерСборкиОбработчикамНаСервере(НовыйНомерСборки)
	
	Обработка = ОбъектОбработки();
	НомераВерсииКонфигурации = СтрРазделить(ВерсияКонфигурации, ".");
	МаксНомерРедакции = Число(НомераВерсииКонфигурации[1]);
	МаксНомерПодРедакции = Число(НомераВерсииКонфигурации[2]);
	ОбработчикиОднойБиблиотеки = Истина;
	УстановленаВерсия = Новый Массив;
	ПодсистемаПредыдущего = Неопределено;
	Для Каждого ИдСтроки Из Элементы.ОбработчикиОбновления.ВыделенныеСтроки Цикл
		Обработчик = Объект.ОбработчикиОбновления.НайтиПоИдентификатору(ИдСтроки);
		Если ПодсистемаПредыдущего = Неопределено Тогда
			ПодсистемаПредыдущего = Обработчик.Подсистема;
		КонецЕсли;
		Если СтрЧислоВхождений(Обработчик.Версия, ".") = 3 Тогда
			
			НомераВерсии = СтрРазделить(Обработчик.Версия, ".");
			НомераВерсии[3] = Формат(НовыйНомерСборки, "ЧН=0; ЧГ=0");
			
			Обработчик.Версия = СтрСоединить(НомераВерсии, ".");
			Обработчик.ВерсияЧислом = Обработка.ВерсияЧислом(Обработчик.Версия);
			Обработчик.Изменен = Истина;
			
			УстановленаВерсия.Добавить(Обработчик);
			
			МаксНомерРедакции = Макс(Число(НомераВерсии[1]), МаксНомерРедакции);
			МаксНомерПодРедакции = Макс(Число(НомераВерсии[2]), МаксНомерПодРедакции);
			
			Если ПодсистемаПредыдущего <> Обработчик.Подсистема Тогда
				ОбработчикиОднойБиблиотеки = Ложь;
			КонецЕсли;
			ПодсистемаПредыдущего = Обработчик.Подсистема;
		КонецЕсли;
	КонецЦикла;
	
	Если ОбработчикиОднойБиблиотеки Тогда
		Для Каждого Обработчик Из УстановленаВерсия Цикл
			НомераВерсии = СтрРазделить(Обработчик.Версия, ".");
			НомераВерсии[1] = Формат(МаксНомерРедакции, "ЧН=0; ЧГ=0");
			НомераВерсии[2] = Формат(МаксНомерПодРедакции, "ЧН=0; ЧГ=0");
			Обработчик.Версия = СтрСоединить(НомераВерсии, ".");
			Обработчик.ВерсияЧислом = Обработка.ВерсияЧислом(Обработчик.Версия);
			НомераВерсии.Удалить(0);
			Обработчик.РедакцияЧислом = Обработка.ВерсияЧислом(СтрСоединить(НомераВерсии, "."));
		КонецЦикла;
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ПереключательФормы

&НаКлиенте
Процедура УстановитьУпрощенныйРежим()
	
	РасширенныйРежимФормы = Ложь;
	Элементы.ПереключитьРежимФормы.Заголовок = НСтр("ru = 'Перейти в расширенный режим'");
	УстановитьВидимостьЭлементовРежимаФормы();
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьРасширенныйРежим()
	
	РасширенныйРежимФормы = Истина;
	Элементы.ПереключитьРежимФормы.Заголовок = НСтр("ru = 'Перейти в упрощенный режим'");
	УстановитьВидимостьЭлементовРежимаФормы();
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьВидимостьЭлементовРежимаФормы()
	
	Элементы.СохранитьВРепозиторий.Видимость = РасширенныйРежимФормы;
	Элементы.СохранитьВРепозиторийВсеОбработчики.Видимость = РасширенныйРежимФормы;
	Элементы.ГруппаНастройкиЗагрузкиВыгрузки.Видимость = РасширенныйРежимФормы;
	Элементы.ПоказатьНастройкиERP.Видимость = РасширенныйРежимФормы;
	Элементы.ГруппаОтладка.Видимость = РасширенныйРежимФормы;
	
КонецПроцедуры

#КонецОбласти

&НаСервере
Функция ОбъектОбработки()
	Возврат РеквизитФормыВЗначение("Объект");
КонецФункции

&НаКлиенте
Функция КаталогНастроек()
	Возврат СтрЗаменить(Объект.КаталогSRC, "\src\","\.settings\");
КонецФункции

&НаКлиенте
Функция ВременныйКаталог()
#Если Не ВебКлиент Тогда
	ПутьККаталогу = ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(ПолучитьИмяВременногоФайла());
	СоздатьКаталог(ПутьККаталогу);
	Возврат ПутьККаталогу;
#КонецЕсли
	
	Возврат "";
КонецФункции

&НаКлиенте
Процедура ЗаписатьИнформациюОбОшибке(ФайлРезультата)
	
	Если ЗначениеЗаполнено(ФайлРезультата) Тогда
		ТекстСообщения = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		Результат = Новый ТекстовыйДокумент;
		Результат.УстановитьТекст(ТекстСообщения);
		Результат.Записать(ФайлРезультата);
	КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура ИнициализироватьКонстантыОбработки()
	
	ВерсияКонфигурации = Метаданные.Версия;
	НоваяВерсияКонфигурации = Метаданные.Версия;
	
	Обработка = ОбъектОбработки();
	
	СтатусНеобходимАнализ = НСтр("ru = 'Необходим анализ'");
	СтатусИзмененаПроцедураПроверки = НСтр("ru = 'Изменена процедура проверки'");
	СтатусЧтениеНизкогоПорядка = НСтр("ru = 'Чтение низкого порядка'");
	РазрабатываемыеПодсистемы = Новый ФиксированныйМассив(Обработка.РазрабатываемыеПодсистемы());
	
	МножественноеЧисло = Новый ФиксированноеСоответствие(Обработка.МножественноеЧисло);
	ЕдинственноеЧисло = Новый ФиксированноеСоответствие(Обработка.ЕдинственноеЧисло);
	
	АнглийскиеКлассы = Новый Соответствие;
	АнглийскиеКлассы.Вставить("Константы", "Constants");
	АнглийскиеКлассы.Вставить("Справочники", "Catalogs");
	АнглийскиеКлассы.Вставить("Документы", "Documents");
	АнглийскиеКлассы.Вставить("ЖурналыДокументов", "DocumentJournals");
	АнглийскиеКлассы.Вставить("Обработки", "DataProcessors");
	АнглийскиеКлассы.Вставить("Перечисления", "Enums");
	АнглийскиеКлассы.Вставить("ПланыВидовХарактеристик", "ChartsOfCharacteristicTypes");
	АнглийскиеКлассы.Вставить("ПланыОбмена", "ExchangePlans");
	АнглийскиеКлассы.Вставить("ПланыСчетов", "ChartsOfAccounts");
	АнглийскиеКлассы.Вставить("ПланыВидовРасчета", "ChartsOfCalculationTypes");
	АнглийскиеКлассы.Вставить("РегистрыСведений", "InformationRegisters");
	АнглийскиеКлассы.Вставить("РегистрыНакопления", "AccumulationRegisters");
	АнглийскиеКлассы.Вставить("РегистрыБухгалтерии", "AccountingRegisters");
	АнглийскиеКлассы.Вставить("РегистрыРасчета", "CalculationRegisters");
	АнглийскиеКлассы.Вставить("БизнесПроцессы", "BusinessProcesses");
	АнглийскиеКлассы.Вставить("Задачи", "Tasks");
	
	АнглийскиеИмена =  Новый ФиксированноеСоответствие(АнглийскиеКлассы);
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ПолучитьПараметрыИзСтроки(Знач СтрокаПараметров)
	
	Результат = Новый Структура;
	
	СимволДвойныеКавычки = Символ(34); // (")
	
	МассивПодстрок = СтрРазделить(СтрокаПараметров, ";");
	
	Для Каждого СтрокаПараметра Из МассивПодстрок Цикл
		
		ПозицияПервогоЗнакаРавенства = СтрНайти(СтрокаПараметра, "=");
		
		// Получаем имя параметра
		ИмяПараметра = СокрЛП(Лев(СтрокаПараметра, ПозицияПервогоЗнакаРавенства - 1));
		
		// Получаем значение параметра.
		ЗначениеПараметра = СокрЛП(Сред(СтрокаПараметра, ПозицияПервогоЗнакаРавенства + 1));
		
		Если  Лев(ЗначениеПараметра, 1) = СимволДвойныеКавычки
			И Прав(ЗначениеПараметра, 1) = СимволДвойныеКавычки Тогда
			
			ЗначениеПараметра = Сред(ЗначениеПараметра, 2, СтрДлина(ЗначениеПараметра) - 2);
			
		КонецЕсли;
		
		Если Не ПустаяСтрока(ИмяПараметра) Тогда
			
			Результат.Вставить(ИмяПараметра, ЗначениеПараметра);
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Результат;
КонецФункции

&НаКлиенте
Функция ДобавитьРазделительПутиВКонец(Знач Путь)
	
	Если ПустаяСтрока(Путь) Тогда
		Возврат Путь;
	КонецЕсли;
	
	РазделительПути = ПолучитьРазделительПути();
	Если Прав(Путь, 1) <> РазделительПути Тогда
		Путь = Путь + РазделительПути;
	КонецЕсли;
	
	Возврат Путь;
	
КонецФункции

&НаКлиенте
Процедура ОформитьГруппуНастроек()
	
	ШаблонПредставления = НСтр("ru = 'Сохранять в %1'");
	Приемник = Объект.КаталогSRC;
	Если НЕ ЗначениеЗаполнено(Объект.КаталогSRC) Тогда
		Приемник = НСтр("ru = '<Укажите каталог src репозитория>'");
	КонецЕсли;
	
	ПредставлениеГруппы = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонПредставления, Приемник);
	
	Если Элементы.КаталогФайловОшибок.Видимость Тогда
		ШаблонПредставления =  ШаблонПредставления + " " + НСтр("ru = 'Ошибки: %2'");
		КаталогОшибок = КаталогФайловОшибок;
		Если НЕ ЗначениеЗаполнено(КаталогФайловОшибок) Тогда
			КаталогОшибок = НСтр("ru = '<Укажите каталог ошибок>'");
		КонецЕсли;
		ПредставлениеГруппы = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонПредставления, Приемник, КаталогОшибок);
	КонецЕсли;
	
	Элементы.ГруппаНастройкиЗагрузкиВыгрузки.ЗаголовокСвернутогоОтображения = ПредставлениеГруппы;
	
КонецПроцедуры 

&НаКлиенте
Процедура ДиалогВыбораКаталогаЗавершение(ВыбранныйКаталог, ИмяРеквизита) Экспорт

	Если ВыбранныйКаталог <> "" Тогда
		Если ИмяРеквизита = "КаталогФайловОшибок" Тогда
			ЭтотОбъект[ИмяРеквизита] = ВыбранныйКаталог + ?(ЗначениеЗаполнено(ВыбранныйКаталог),ПолучитьРазделительПути(),"");
		Иначе
			Объект[ИмяРеквизита] = ВыбранныйКаталог + ?(ЗначениеЗаполнено(ВыбранныйКаталог),ПолучитьРазделительПути(),"");
		КонецЕсли;
		ОформитьГруппуНастроек();
	КонецЕсли; 
	
КонецПроцедуры

&НаКлиенте
Функция ФильтрФайловРезервнойКопии()
	Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Описание обработчиков (*.handlers)|*.handlers|Все файлы (%1)|%1'"), ПолучитьМаскуВсеФайлы());
КонецФункции

&НаКлиенте
Процедура ДиалогВыбораФайлаЗавершение(ВыбранныйФайл, ДополнительныеПараметры) Экспорт

	Если ВыбранныйФайл <> Неопределено Тогда
		ИмяФайлаРезервнойКопии = ВыбранныйФайл[0];
		Адрес = ПоместитьВоВременноеХранилище(ДанныеДляСохраненияВФайл());
		ПараметрыСохранения = ФайловаяСистемаКлиент.ПараметрыСохраненияФайла();
		ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, Адрес, ИмяФайлаРезервнойКопии, ПараметрыСохранения);
	КонецЕсли; 
	
КонецПроцедуры

&НаКлиенте
Процедура ВыбратьФайлПослеПомещенияФайла(ВыбранныйФайл, ДополнительныеПараметры) Экспорт

	Если ВыбранныйФайл <> Неопределено Тогда
		ЗагрузитьДанныеИзФайла(ВыбранныйФайл.Хранение);
	КонецЕсли; 
	
КонецПроцедуры

&НаСервере
Функция ДанныеДляСохраненияВФайл()
	
	Данные = Новый Структура;
	Данные.Вставить("ОбработчикиОбновления", Объект.ОбработчикиОбновления.Выгрузить());
	Данные.Вставить("ЧитаемыеОбъекты", Объект.ЧитаемыеОбъекты.Выгрузить());
	Данные.Вставить("ИзменяемыеОбъекты", Объект.ИзменяемыеОбъекты.Выгрузить());
	Данные.Вставить("БлокируемыеОбъекты", Объект.БлокируемыеОбъекты.Выгрузить());
	Данные.Вставить("ПриоритетыВыполнения", Объект.ПриоритетыВыполнения.Выгрузить());
	Данные.Вставить("КонфликтыОбработчиков", Объект.КонфликтыОбработчиков.Выгрузить());
		
	Возврат ЗначениеВСтрокуВнутр(Данные);
	
КонецФункции

&НаСервере
Процедура ЗагрузитьДанныеИзФайла(Адрес)
	
	ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(Адрес); // ДвоичныеДанные
	ВременныйФайл = ПолучитьИмяВременногоФайла(".tmp");
	ДвоичныеДанныеФайла.Записать(ВременныйФайл);
	Текст = Новый ТекстовыйДокумент;
	Текст.Прочитать(ВременныйФайл);
	Строка = Текст.ПолучитьТекст();
	Данные = ЗначениеИзСтрокиВнутр(Строка);
	ФайловаяСистема.УдалитьВременныйФайл(ВременныйФайл);
	
	Объект.ОбработчикиОбновления.Загрузить(Данные.ОбработчикиОбновления);
	Объект.ЧитаемыеОбъекты.Загрузить(Данные.ЧитаемыеОбъекты);
	Объект.ИзменяемыеОбъекты.Загрузить(Данные.ИзменяемыеОбъекты);
	Объект.БлокируемыеОбъекты.Загрузить(Данные.БлокируемыеОбъекты);
	Объект.ПриоритетыВыполнения.Загрузить(Данные.ПриоритетыВыполнения);
	Объект.КонфликтыОбработчиков.Загрузить(Данные.КонфликтыОбработчиков);
	
	Обработка = ОбъектОбработки();
	ОбновитьДанныеФормы(Обработка);
	
	ТекущаяБиблиотека = "";
	Модифицированность = Ложь;
	
КонецПроцедуры

&НаСервере
Процедура ПриИзмененииОбъектаПоискаНаСервере(ИмяТабличнойЧасти, ТекстОтбора)
	
	Если ЗначениеЗаполнено(ТекстОтбора) Тогда
		Отбор = ЗаполнитьПолеОтбораПоОбъектуНаСервере(ИмяТабличнойЧасти, ТекстОтбора);
		УстановитьОтборОбработчиков(Отбор);
	Иначе
		ОтключитьОтборОбработчиков("Отбор" + ИмяТабличнойЧасти);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ОбновитьОтборыОбработчиков()
	
	Если Элементы.ОбработчикиОбновления.ОтборСтрок <> Неопределено Тогда
		Если Элементы.ОбработчикиОбновления.ОтборСтрок.Свойство("ОтборЧитаемыеОбъекты") <> Неопределено Тогда
			ПриИзмененииОбъектаПоискаНаСервере("ЧитаемыеОбъекты", ЧитаемыйОбъект);
		КонецЕсли;
		Если Элементы.ОбработчикиОбновления.ОтборСтрок.Свойство("ОтборИзменяемыеОбъекты") <> Неопределено Тогда
			ПриИзмененииОбъектаПоискаНаСервере("ИзменяемыеОбъекты", ИзменяемыйОбъект);
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура ОбновитьДанныеФормы(Обработка)
	
	ЗаполнитьБыстрыеОтборы();
	ОбновитьОтборыОбработчиков();
	Если Обработка.МодулиПодсистем <> Неопределено Тогда
		МодулиПодсистем = Новый ФиксированнаяСтруктура(Обработка.МодулиПодсистем);
		ОбновитьСписокБиблиотек(Обработка);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ОбновитьСписокБиблиотек(Обработка)
	
	СписокПодсистем = Элементы.ТекущаяБиблиотека.СписокВыбора;
	СписокПодсистем.Очистить();
	Для Каждого Библиотека Из Обработка.МодулиПодсистем Цикл
		СписокПодсистем.Добавить(Библиотека.Ключ);
	КонецЦикла;
	СписокПодсистем.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
	СписокПодсистем.Вставить(0,"");
	
КонецПроцедуры

&НаСервере
Процедура УстановитьОтборОбработчиков(Отбор)
	
	Если ЗначениеЗаполнено(Элементы.ОбработчикиОбновления.ОтборСтрок) Тогда
		ТекущийОтбор = Новый Структура(Элементы.ОбработчикиОбновления.ОтборСтрок);
		Для Каждого НовыйОтбор Из Отбор Цикл
			ТекущийОтбор.Вставить(НовыйОтбор.Ключ, НовыйОтбор.Значение);
		КонецЦикла;
		Элементы.ОбработчикиОбновления.ОтборСтрок = Новый ФиксированнаяСтруктура(ТекущийОтбор);
	Иначе
		Элементы.ОбработчикиОбновления.ОтборСтрок = Новый ФиксированнаяСтруктура(Отбор);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ОтключитьОтборОбработчиков(ИмяПоля)
	
	Если Элементы.ОбработчикиОбновления.ОтборСтрок = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если НЕ Элементы.ОбработчикиОбновления.ОтборСтрок.Свойство(ИмяПоля) Тогда
		Возврат;
	КонецЕсли;
	
	Если СтрНайти(ИмяПоля, "Отбор") > 0 Тогда
		Отбор = Новый Структура(ИмяПоля, Элементы.ОбработчикиОбновления.ОтборСтрок[ИмяПоля]);
		НайденныеСтроки = Объект.ОбработчикиОбновления.НайтиСтроки(Отбор);
		Для Каждого Строка Из НайденныеСтроки Цикл
			Строка[ИмяПоля] = "";
		КонецЦикла;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Элементы.ОбработчикиОбновления.ОтборСтрок)
		И Элементы.ОбработчикиОбновления.ОтборСтрок.Свойство(ИмяПоля) Тогда
		
		ТекущийОтбор = Новый Структура(Элементы.ОбработчикиОбновления.ОтборСтрок);
		ТекущийОтбор.Удалить(ИмяПоля);
		Если ЗначениеЗаполнено(ТекущийОтбор) Тогда
			Элементы.ОбработчикиОбновления.ОтборСтрок = Новый ФиксированнаяСтруктура(ТекущийОтбор);
		Иначе
			Элементы.ОбработчикиОбновления.ОтборСтрок = Неопределено;
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура УстановитьБыстрыйОтбор(ИмяБыстрогоОтбора)
	
	Если ТипЗнч(ИмяБыстрогоОтбора) = Тип("ЭлементСпискаЗначений") Тогда
		ИмяБыстрогоОтбора = ИмяБыстрогоОтбора.Значение;
	КонецЕсли;
	
	Если ИмяБыстрогоОтбора = "НеобходимАнализ" Тогда
		Отбор = Новый Структура("СтатусПроблемы", СтатусНеобходимАнализ);
		
	ИначеЕсли ИмяБыстрогоОтбора = "Отложенно" Тогда
		Отбор = Новый Структура("РежимВыполнения", НСтр("ru = 'Отложенно'"));
		
	ИначеЕсли ИмяБыстрогоОтбора = "Монопольно" Тогда
		Отбор = Новый Структура("РежимВыполнения", НСтр("ru = 'Монопольно'"));
		
	ИначеЕсли ИмяБыстрогоОтбора = "Оперативно" Тогда
		Отбор = Новый Структура("РежимВыполнения", НСтр("ru = 'Оперативно'"));
		
	ИначеЕсли ИмяБыстрогоОтбора = "Последовательно" Тогда
		Отбор = Новый Структура("РежимВыполненияОтложенныхОбработчиков", НСтр("ru = 'Последовательно'"));
		
	ИначеЕсли ИмяБыстрогоОтбора = "Параллельно" Тогда
		Отбор = Новый Структура("РежимВыполненияОтложенныхОбработчиков", НСтр("ru = 'Параллельно'"));
		
	ИначеЕсли ИмяБыстрогоОтбора = "НачальноеЗаполнение" Тогда
		Отбор = Новый Структура("НачальноеЗаполнение", Истина);
		
	ИначеЕсли ИмяБыстрогоОтбора = "ИзмененаПроцедураПроверки" Тогда
		Отбор = Новый Структура("ИзмененаПроцедураПроверки", Истина);
		
	ИначеЕсли ИмяБыстрогоОтбора = "ЧтениеНизкогоПорядка" Тогда
		Отбор = Новый Структура("ЧтениеНизкогоПорядка", Истина);
		
	ИначеЕсли ИмяБыстрогоОтбора = "Обязательный" Тогда
		Отбор = Новый Структура("ВыполнятьВГруппеОбязательных", Истина);
		
	ИначеЕсли ИмяБыстрогоОтбора = "Многопоточный" Тогда
		Отбор = Новый Структура("Многопоточный", Истина);
		
	ИначеЕсли ИмяБыстрогоОтбора = "ЗаписьЧитаемых" Тогда
		Отбор = Новый Структура("ЗаписьЧитаемых", Истина);
		
	ИначеЕсли ИмяБыстрогоОтбора = "ПовторнаяЗапись" Тогда
		Отбор = Новый Структура("ПовторнаяЗапись", Истина);
		
	ИначеЕсли ИмяБыстрогоОтбора = "ТехническийПроект" Тогда
		Отбор = Новый Структура("ТехническийПроект", Истина);
		
	Иначе
		ОтключитьОтборОбработчиков("СтатусПроблемы");
		ОтключитьОтборОбработчиков("ИзмененаПроцедураПроверки");
		ОтключитьОтборОбработчиков("ЧтениеНизкогоПорядка");
		ОтключитьОтборОбработчиков("РежимВыполнения");
		ОтключитьОтборОбработчиков("РежимВыполненияОтложенныхОбработчиков");
		ОтключитьОтборОбработчиков("НачальноеЗаполнение");
		ОтключитьОтборОбработчиков("ВыполнятьВГруппеОбязательных");
		ОтключитьОтборОбработчиков("Многопоточный");
		ОтключитьОтборОбработчиков("ЗаписьЧитаемых");
		ОтключитьОтборОбработчиков("ПовторнаяЗапись");
		ОтключитьОтборОбработчиков("ТехническийПроект");
		Возврат;
	КонецЕсли;
	
	УстановитьОтборОбработчиков(Отбор);
	
КонецПроцедуры

&НаСервере
Функция ЗаполнитьПолеОтбораПоОбъектуНаСервере(ИмяТабличнойЧасти, Текст)
	
	Запрос = Новый Запрос(
		"ВЫБРАТЬ РАЗЛИЧНЫЕ
		|	Т.Ссылка КАК Ссылка
		|ПОМЕСТИТЬ вт
		|ИЗ
		|	&тз КАК Т
		|ГДЕ
		|	Т.ОбъектМетаданных ПОДОБНО &СтрокаПоиска СПЕЦСИМВОЛ ""~""");
	Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
	Запрос.УстановитьПараметр("тз", Объект[ИмяТабличнойЧасти].Выгрузить());
	Запрос.УстановитьПараметр("СтрокаПоиска", "%" + ОбщегоНазначения.СформироватьСтрокуДляПоискаВЗапросе(Текст) + "%");
	Запрос.Выполнить();
	УникальныеСсылки = Запрос.МенеджерВременныхТаблиц.Таблицы["вт"].ПолучитьДанные().Выгрузить().ВыгрузитьКолонку("Ссылка");
	
	ИмяПоляОтбора = "Отбор" + ИмяТабличнойЧасти;
	Отбор = Новый Структура("Ссылка");
	Для Каждого Ссылка Из УникальныеСсылки Цикл
		Отбор.Ссылка = Ссылка;
		Обработчики = Объект.ОбработчикиОбновления.НайтиСтроки(Отбор);
		Для Каждого Обработчик Из Обработчики Цикл
			Обработчик[ИмяПоляОтбора] = Текст;
		КонецЦикла;
	КонецЦикла;
	
	Отбор = Новый Структура(ИмяПоляОтбора, Текст);	
	Возврат Отбор;
	
КонецФункции

&НаСервере
Процедура УдалитьОписаниеОбработчиков(Обработчики)
	
	Если ТипЗнч(Обработчики) = Тип("Массив") Тогда
		Для Каждого ИдентификаторСтроки Из Обработчики Цикл
			ОчиститьСвязанныеДанныеОбработчика(ИдентификаторСтроки);
		КонецЦикла;
	Иначе
		ОчиститьСвязанныеДанныеОбработчика(Обработчики);
	КонецЕсли;
	
	ПроверитьКонфликтыНаСервере();
	
КонецПроцедуры

&НаСервере
Процедура ОчиститьСвязанныеДанныеОбработчика(ИдСтроки)
	
	Обработчик = Объект.ОбработчикиОбновления.НайтиПоИдентификатору(ИдСтроки);
	СсылкаОбработчика = Обработчик.Ссылка;
	УдалитьДанныеОбработчика("ОбработчикиОбновления", СсылкаОбработчика);
	УдалитьДанныеОбработчика("ЧитаемыеОбъекты", СсылкаОбработчика);
	УдалитьДанныеОбработчика("ИзменяемыеОбъекты", СсылкаОбработчика);
	УдалитьДанныеОбработчика("БлокируемыеОбъекты", СсылкаОбработчика);
	УдалитьДанныеОбработчика("ПриоритетыВыполнения", СсылкаОбработчика);
	
	Отбор = Новый Структура("ИмяОбъекта", Обработчик.ИмяОбъекта);
	ЕщеОбработчикиОбъекта = Объект.ОбработчикиОбновления.НайтиСтроки(Отбор);
	Для Каждого ЕщеОбработчик Из ЕщеОбработчикиОбъекта Цикл
		ЕщеОбработчик.Изменен = Истина;
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Процедура УдалитьДанныеОбработчика(ИмяТЧ, СсылкаОбработчика)
	
	ТабличнаяЧасть = Объект[ИмяТЧ];
	УдалитьСтрокиТаблицы(ТабличнаяЧасть, Новый Структура("Ссылка", СсылкаОбработчика));
	Если ИмяТЧ = "ПриоритетыВыполнения" Тогда
		УдалитьСтрокиТаблицы(ТабличнаяЧасть, Новый Структура("Обработчик2", СсылкаОбработчика));
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура УдалитьСтрокиТаблицы(Таблица, Отбор)
	
	НайденныеСтроки = Таблица.НайтиСтроки(Отбор);
	Для Каждого СтрокаТЧ Из НайденныеСтроки Цикл
		Таблица.Удалить(СтрокаТЧ);
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Процедура ПроверитьКонфликтыНаСервере()
	
	Обработка = ОбъектОбработки();
	ОбновитьСведенияОКонфликтахОбработчиков(Обработка);
	ЗначениеВРеквизитФормы(Обработка, "Объект");
	
КонецПроцедуры

&НаСервере
Функция ВыгрузитьТаблицыВMXL(Ссылка = Неопределено, ТаблицыВыгрузки = "", КаталогВыгрузкиТЧ = "")
	
	Если ПустаяСтрока(ТаблицыВыгрузки) Тогда
		ТаблицыВыгрузки = "ЧитаемыеОбъекты,ИзменяемыеОбъекты,БлокируемыеОбъекты,ПриоритетыВыполнения,КонфликтыОбработчиков";
	КонецЕсли;
	
	Обработка = ОбъектОбработки().Метаданные();
	Результат = Новый Структура;
	
	Построитель = Новый ПостроительОтчета;
	Для Каждого ТЧ Из Обработка.ТабличныеЧасти Цикл
		
		Если Ссылка <> Неопределено И СтрНайти(ТаблицыВыгрузки, ТЧ.Имя) = 0  Тогда
			Продолжить;
		КонецЕсли;
		
		ДанныеТЧ = Объект[ТЧ.Имя].Выгрузить();
		Если Ссылка <> Неопределено Тогда
			ДанныеТЧ = ДанныеОбработчика(ТЧ.Имя, Ссылка);
		КонецЕсли;
		Если ТЧ.Имя = "ПриоритетыВыполнения" Тогда
			ДанныеТЧ.Сортировать("Процедура1,Процедура2");
		ИначеЕсли ТЧ.Имя = "КонфликтыОбработчиков" Тогда
			ДанныеТЧ.Сортировать("ОбъектМетаданных,ПроцедураПисатель,ПроцедураЧитательИлиПисатель2");
		ИначеЕсли ТЧ.Имя = "ЧтениеНизкогоПорядка" Тогда
			ДанныеТЧ.Сортировать("ОбъектМетаданных,ПроцедураЧитатель,ПроцедураПисатель");
		КонецЕсли;
		ТабДок = Новый ТабличныйДокумент;
		Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ДанныеТЧ);
		
		
		Построитель.Вывести(ТабДок);
		
		Область = ТабДок.Область("R1:R3");
		ТабДок.УдалитьОбласть(Область, ТипСмещенияТабличногоДокумента.ПоВертикали);
		ПервыеДвеКолонки = "R1C1:R" + Формат(ТабДок.ВысотаТаблицы, "ЧГ=0") + "C2";
		Область = ТабДок.Область(ПервыеДвеКолонки);
		ТабДок.УдалитьОбласть(Область, ТипСмещенияТабличногоДокумента.ПоГоризонтали);
		
		Область = ТабДок.Область();
		Область.ШиринаКолонки = 20;
		Область.РазмещениеТекста = ТипРазмещенияТекстаТабличногоДокумента.Обрезать;
		
		Результат.Вставить(ТЧ.Имя, ТабДок);
		
		Если НЕ ПустаяСтрока(КаталогВыгрузкиТЧ) Тогда
			ИмяФайла = КаталогВыгрузкиТЧ + "\" + ТЧ.Имя + ".mxl";
			ТабДок.Записать(ИмяФайла);
			Результат.Вставить(ТЧ.Имя, ИмяФайла);
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

&НаСервере
Функция ДанныеОбработчика(ИмяТЧ, Ссылка)
	
	Если ИмяТЧ = "ОбработчикиОбновления" Тогда
		ДанныеТЧ = Объект[ИмяТЧ].Выгрузить();
		
	ИначеЕсли СтрНайти("ЧитаемыеОбъекты,ИзменяемыеОбъекты,БлокируемыеОбъекты,ПриоритетыВыполнения", ИмяТЧ) > 0 Тогда
		Отбор = Новый Структура("Ссылка", Ссылка);
		ДанныеТЧ = Объект[ИмяТЧ].Выгрузить(Отбор);
		
	ИначеЕсли ИмяТЧ = "КонфликтыОбработчиков" Тогда
		Отбор = Новый Структура("ОбработчикПисатель", Ссылка);
		ДанныеТЧ = Объект[ИмяТЧ].Выгрузить(Отбор);
		Отбор = Новый Структура("ОбработчикЧитательИлиПисатель2", Ссылка);
		ДанныеТЧ2 = Объект[ИмяТЧ].Выгрузить(Отбор);
		ОбщегоНазначенияКлиентСервер.ДополнитьТаблицу(ДанныеТЧ2, ДанныеТЧ);
		
	ИначеЕсли ИмяТЧ = "ЧтениеНизкогоПорядка" Тогда
		Отбор = Новый Структура("Читатель", Ссылка);
		ДанныеТЧ = Объект[ИмяТЧ].Выгрузить(Отбор);
		
	КонецЕсли;
	
	Возврат ДанныеТЧ;
	
КонецФункции

&НаСервере
Процедура РассчитатьОчередьНаСервере()
	
	ИтерацииОбновления = Неопределено; // ОбновлениеИнформационнойБазыСлужебный.ИтерацииОбновления();
	Если ИтерацииОбновления <> Неопределено Тогда
		Обработка = ОбъектОбработки();
		Обработка.ЗаполнитьНомерОчереди(ИтерацииОбновления);
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти
